当我使用document.body.innerHTML + = newHtmlText时,页内JavaScript停止

时间:2017-07-20 12:38:40

标签: javascript html google-chrome-extension

有谁知道为什么如果你使用document.body.innerHTML += "content";页面上的JavaScript停止工作?我有以下代码:

document.addEventListener('contextmenu', function (e) {
    e.preventDefault();
    try {
        document.getElementById('menu').remove();
    } catch (x) {
        //
    }
    var newHtmlText = "<div id='menu'>";
    newHtmlText += "<div class='menu-item' id='menu-back' onclick='window.history.back();'>" +
        "<div class='fa fa-arrow-left icon'></div><div class='text'>Back</div><div class='clear'></div></div>";
    newHtmlText += "<div class='menu-item' id='menu-forward' onclick='window.history.forward();'>" +
        "<div class='fa fa-arrow-right icon'></div><div class='text'>Forward</div><div class='clear'></div></div>";
    newHtmlText += "<div class='menu-item' id='menu-reload' onclick='location.reload();'>" +
        "<div class='fa fa-repeat icon'></div><div class='text'>Reload</div><div class='clear'></div></div>";
    newHtmlText += "<hr />";
    newHtmlText += "<div class='menu-item' id='menu-home' onclick='location.href = \"/\";'>" +
        "<div class='fa fa-home icon'></div><div class='text'>Home</div><div class='clear'></div></div>";
    newHtmlText += "</div>";
    document.body.innerHTML += newHtmlText;
    var menu = document.getElementById('menu');
    menu.style.left = (e.clientX) + "px";
    menu.style.top = (e.clientY) + "px";
});

每次打开上下文菜单时,JavaScript都会停止工作。这不是它唯一一次这样做。

3 个答案:

答案 0 :(得分:4)

使用x.innerHTML += y相当于x.innerHTML = x.innerHTML + y;

这意味着您完全使用新文档覆盖旧文档 - 它可能在视觉上看起来相同,但在引擎盖下,您只是对所有内容的每一个引用都进行了修改。

如果页面中其他位置的JavaScript使用类似var container = document.getElementById('container');的内容,为了保存引用,那么该引用现在已经消失了。

如果有任何事件侦听器绑定到文档中的元素,那么这些元素也会消失,因为元素被核化并替换为相同的元素。

如果要将上下文菜单添加到页面,则应执行以下操作:

var menu = document.createElement('div');
menu.id = 'menu';
menu.innerHTML = "Your menu HTML here";
document.body.appendChild(menu);

这会将新元素添加到页面中而不需要整理任何内容。

答案 1 :(得分:2)

user id

有三件事:

  1. 读取document.body.innerHTML += "content";
  2. 的值
  3. 修改该值
  4. 使用新值
  5. 覆盖innerHTML

    删除页面,然后创建

    script elements inserted with innerHTML are not executed开始,这会杀死JS。

    请勿使用innerHTML附加数据。生成DOM节点(使用innerHTMLcreateElement和朋友),然后附加它们(使用createTextNodeappendChild等等。)

答案 2 :(得分:1)

正如其他人所解释的那样,使用:

document.body.innerHTML += newHtmlText;

删除整个页面并重新创建。这导致:

  • 放置在要与DOM断开连接的元素上的所有事件侦听器。如果没有对DOM元素或侦听器函数(例如命名函数)的外部引用,则将对侦听器进行垃圾回收(取决于浏览器)。
  • 任何保存的元素引用现在都将引用不再存在于DOM中的元素。这些DOM节点及其子节点不会被垃圾收集,因为仍然存在对它们的引用。使用这些引用的JavaScript不会抛出错误,除非它试图找到对该元素不再连接的关联DOM节点的引用(祖先节点,例如.parentNode)。但是,JavaScript在操作显示的DOM时将完全无效,因为它将使用对DOM中不再存在的元素的引用。
  • 整个旧DOM将被垃圾收集(取决于浏览器),除了任何元素及其子节点,它们的引用保存在JavaScript代码的其他地方。

这几乎肯定会完全打破现有的大多数JavaScript。

使用.insertAdjacentHTML()

添加 HTML文本的正确方法是使用element.insertAdjacentHTML(relativeLocation, HTMLtext),而不会干扰现有内容。使用.insertAdjacentHTML(),您可以在相对于引用元素的四个不同位置添加HTML文本。 relativeLocation的值可以是:

  • 'beforebegin' :元素之前
  • 'afterbegin' :就在元素的开头(比如添加新的.firstChild),但您可以添加尽可能多的子项(尽可能多的HTML文本)
  • 'beforeend' :在元素结束之前(如.appendChild(),但您可以根据需要添加任意数量的子项(尽可能多的HTML文本)。< / LI>
  • 'afterend' :在元素之后(如element.parentNode.insertBefore(newElement,element.nextSibling),但您可以根据需要添加尽可能多的parentNode子项(尽可能多的HTML文本))。注意:如果您要插入元素,也可以使用:element.insertAdjacentElement('afterend',newElement)

对于你想做的事,你会使用:

document.body.insertAdjacentHTML('beforeend',newHtmlText);