Edit, save, self-modifying HTML document; format generated HTML, JavaScript

眉间皱痕 提交于 2019-11-25 22:58:03

Your replace function replaces until the /textarea> that is in your clone variable. It doesn't do it from the first file because there's a newline character after textarea in the html. One way to fix it would be to add a newline character in the generated html. Like this:

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>"];

I'm not sure what is breaking the third-generation clone so that it results in the js info being output to the page, but it would probably be better to use an actual document object to clone/manipulate the original and output its contents as string for the Blob object. For example, I tested using your base saveFile.html with the following changes:

//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"});

The only downsides I am seeing are:

  1. This may be hard to expand into a more generic framework for generating a "live HTML file" of current state of loaded HTML page (though it shouldn't be more complicated than your example approach).

  2. The string returned by clone.documentElement.outerHTML appears to drop the document type declaration to a simple element so that :

is not in the output string. You could probably use something like:

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

as a workaround. Or, for something more robust:

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

var clone_string = [doc_doctype + clone.documentElement.outerHTML];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!