2015-05-31 2 views
2

Мотивация: https://stackoverflow.com/questions/28120689/create-self-modifying-html-page-on-boxРедактировать, сохранять, самомодифицировать HTML-документ; Формат генерируется HTML, JavaScript

Ошибка: String побег, форматирование html, js генерируется первоначальный отредактированы, сохранены html, js

например,

а) если она открыта «saveFile.html "в локальном браузере;

b) тип "abc" в textarea;

c) нажмите save file кнопка;

d) щелчок Save по телефону Save File;

e) file-*[date according to universal time].html сохранен на диске;

f) открыть file-*[date according to universal time].html в браузере;

g) тип "def" в textarea;

h) повторение d), e), f);

i) Ошибка: результат во втором file-*[date according to universal time].html отображает textarea, содержащий текстовое содержимое «abc def»; buttonне отображается в html:

// at rendered `html` from second `file-*[date according to universal time].html` 
// `textarea` containing "abc def" displayed here , 
// `button` _not_ displayed ; following string displayed following `textarea`: 
');"console.log(clone);var file = new Blob([clone], {'type':'text/html'});a.href = URL.createObjectURL(file);a.download = 'file-' + new Date().getTime() + '.html';a.click();}; 

генерируется на линии , "saveFile.html"

+ "var clone = '<!doctype html>'+ document.documentElement.outerHTML.replace(/<textarea>.*<.+textarea>/, '<textarea>'+document.getElementsByTagName('textarea')[0].value+'<\/textarea>');" 

"saveFile.html" v 1.0.0

html, js

<!doctype html> 
<html> 
<!-- saveFile.html 1.0.0 2015 guest271314 edit, save `html` document --> 
<head> 
</head> 
<body> 
<textarea> 
</textarea> 
<button>save file</button> 
<script type="text/javascript"> 
var saveFile = document.getElementsByTagName("button")[0]; 
var input = document.getElementsByTagName("textarea")[0]; 
var a = document.createElement("a"); 

saveFile.onclick = function(e) { 

    var clone = ["<!doctype html><head></head><body><textarea>" 
       + input.value 
       + "</textarea>" 
       + "<button>save file</button>" 
       + "<script type='text/javascript'>" 
       + "var saveFile = document.getElementsByTagName('button')[0];" 
       + "var input = document.getElementsByTagName('textarea')[0];" 
       + "var a = document.createElement('a');" 
       + "saveFile.onclick = function(e) {" 
       + "var clone = '<!doctype html>'+ document.documentElement.outerHTML.replace(/<textarea>.*<.+textarea>/, '<textarea>'+document.getElementsByTagName('textarea')[0].value+'<\/textarea>');" 
       + "console.log(clone);" 
       + "var file = new Blob([clone], {'type':'text/html'});" 
       + "a.href = URL.createObjectURL(file);" 
       + "a.download = 'file-' + new Date().getTime() + '.html';" 
       + "a.click();" 
       + "};" 
       + "</scr"+"ipt>" 
       + "</body>" 
       + "</html>"]; 

    var file = new Blob([clone], {"type":"text/html"}); 
    a.href = URL.createObjectURL(file); 
    a.download = "file-" + new Date().getTime() + ".html"; 
    a.click(); 

}; 
</script> 
</body> 
</html> 
+2

Можете ли вы объяснить более четко и просто, что * должно происходить * против того, что на самом деле происходит? Может быть, дать лучший контекст и для общей концепции? – Anthony

+0

@ Anthony Ожидаемый результат: сохраненный файл после 'click' on" save file "' button', при открытии должен вносить текстовый ввод в элемент 'textarea' из предыдущего документа' html', включая элемент '' 'sibling' button'. Контекст - это попытка создания самомодифицирующего, псевдополиморфного документа 'html', где изменения, сделанные в' textarea', сохраненные в одной версии, отображаются в следующей сохраненной версии. – guest271314

ответ

1

Функция замены заменяет до /textarea>, которая находится в вашей переменной clone. Он не делает этого из первого файла, потому что после textarea в html есть символ новой строки. Один из способов исправить это - добавить символ newline в сгенерированный html. Как это:

var clone = ["<!doctype html><head></head><body><textarea>" 
      + input.value 
     // add newline here 
      + "</textarea>\n" 
      + "<button>save file</button>" 
      + "<script type='text/javascript'>" 
      + "var saveFile = document.getElementsByTagName('button')[0];" 
      + "var input = document.getElementsByTagName('textarea')[0];" 
      + "var a = document.createElement('a');" 
      + "saveFile.onclick = function(e) {" 
      + "var clone = '<!doctype html>'+ document.documentElement.outerHTML.replace(/<textarea>.*<.+textarea>/, '<textarea>'+document.getElementsByTagName('textarea')[0].value+'<\/textarea>');" 
      + "console.log(clone);" 
      + "var file = new Blob([clone], {'type':'text/html'});" 
      + "a.href = URL.createObjectURL(file);" 
      + "a.download = 'file-' + new Date().getTime() + '.html';" 
      + "a.click();" 
      + "};" 
      + "</scr"+"ipt>" 
      + "</body>" 
      + "</html>"]; 
+0

Tried '+ ' \ n');" ',' button' была отображена, но появилась для визуализации новой строки в 'js'; следующая строка, начинающаяся с' '); console.log (clone) 'rendered как текстовая строка , а не 'js' в источнике. – guest271314

+1

см. редактировать, вам нужно добавить \ n после первого" " –

1

Я не уверен, что ломает клон третьего поколения, так что это приводит к информации Js выводится на странице, но это, вероятно, будет лучше использовать реальный объект документа для клонировать/манипулировать оригиналом и выводить его содержимое как строку для объекта Blob. Например, я тестировал с помощью базового saveFile.html со следующими изменениями:

//remove original clone var and replace with: 
var clone = document.cloneNode(true); 

// grab textarea elements from both original document and clone: 
var doc_input = document.getElementsByTagName("textarea")[0]; 
var clone_input = clone.getElementsByTagName("textarea")[0]; 

// set clone textarea's innerHTML to current textarea value: 
clone_input.innerHTML = doc_input.value; 

// use outerHTML of clone.documentElement to get string for Blob 
var clone_string = [clone.documentElement.outerHTML]; 
var file = new Blob([clone_string], {"type":"text/html"}); 

Минусом я вижу, является:

  1. Это может быть трудно расшириться в более общие рамки генерируя «живой HTML-файл» текущего состояния загруженной HTML-страницы (хотя это не должно быть сложнее, чем ваш примерный подход).

  2. Строка, возвращаемая clone.documentElement.outerHTML появляется уронить объявление типа документа к простому элементу так, что:

не в выходной строке. Вероятно, вы могли бы использовать что-то вроде:

var clone_string = ["<!doctype html>" + clone.documentElement.outerHTML]; 

как обходной путь. Или, для чего-то более надежного:

var doc_doctype = new XMLSerializer().serializeToString(document.doctype); 

var clone_string = [doc_doctype + clone.documentElement.outerHTML]; 
+1

https://gist.github.com/crazytonyi/c746c745a273ee1cd6ad – Anthony

+1

Обновлено. Также добавлен v2 html, который просто использует 'serializeToString' вместо' externalHTML'. Убедитесь, что вы протестируете против любых браузеров, с которыми вы хотите работать. – Anthony

Смежные вопросы