【问题标题】:Fire a function when innerHTML of element changes?当元素的innerHTML改变时触发一个函数?
【发布时间】:2018-05-02 20:33:17
【问题描述】:

我想在div 元素的innerHTML 发生变化时触发一个函数。

一直在用element.addEventListener('DOMCharacterDataModified', myFunction()); 进行测试,但它似乎无法正常工作。它在页面加载时触发一次,但之后再也不会触发?请参阅下面的示例代码。

有人可以解决我的任务吗?非常感谢任何帮助!

任务:

  1. 我有一个空的div
  2. 它会随机接收来自外部来源(我无法控制)的数据。
  3. 每次innerHTML发生变化时,我都想触发myFunction()

我当前的示例代码:

var element = document.getElementById('div');

element.addEventListener('DOMCharacterDataModified', myFunction());

function myFunction() {
    console.log(element.innerHTML);
}

setTimeout(function(){
    element.innerHTML = 'Hello World!';
}, 1000);

setTimeout(function(){
    element.innerHTML = 'Hello Space!';
}, 2000);

setTimeouts 可视化来自外部源的数据。

如果可能,它只需要是 JS,但如果 真的 需要,可以使用 jQuery。


提前致谢!

// 接线

【问题讨论】:

  • 如果您能向我们展示代码将会很有帮助
  • 你通常需要一个 MutationObserver,除此之外,你需要尝试一些东西并提出一个特定的问题。
  • @JegadeshBS 我现在添加了一些示例代码并完善了我的问题。
  • .change 事件?
  • @RonRoyston AFAK,它仅适用于 input 类型的元素。不适用于我需要它的divs。

标签: javascript html function innerhtml addeventlistener


【解决方案1】:

使用DOMSubtreeModified事件:

var element = document.getElementById('div');

element.addEventListener('DOMSubtreeModified', myFunction);

function myFunction(e) {
    console.log(element.innerHTML);
}

setTimeout(function(){
    element.innerHTML = 'Hello World!';
}, 1000);

setTimeout(function(){
    element.innerHTML = 'Hello Space!';
}, 2000);
<div id="div"></div>

顺便说一句,DOM 突变事件是deprecated。使用MutationObserver

window.addEventListener('load', function () {
  var element = document.getElementById('div');

  var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
  var observer = new MutationObserver(myFunction);
  observer.observe(element, {
	  childList: true
  });

  function myFunction() {
    console.log(element);
    console.log(element.innerHTML);
  }

  setTimeout(function(){
    element.innerHTML = 'Hello World!';
  }, 1000);

  setTimeout(function(){
    element.innerHTML = 'Hello Space!';
  }, 2000);
});
<div id="div">

Raw snippet on GitHub

【讨论】:

  • 不幸的是,我认为我必须使用旧的 DOM 突变事件,因为此代码正在使用旧版本 Chromium 的自定义图形服务器上运行。因为当我在图形服务器中测试您的代码时它不起作用,但它在我自己的浏览器(Chrome)中确实有效。因此,例如,跨浏览器支持不是问题,我只需要它来处理这种特定情况。你知道每次发生变化时如何让我的示例代码工作吗?谢谢你的帮助! :)
  • @wirrew 你的服务器有什么版本的 Chromium?
  • 似乎是第 33 版。
  • @wirrew 改了我的答案,请看一下
  • 运行代码sn -p 好像会导致页面崩溃。但它不适用于图形服务器(仅当我在浏览器中运行文件时)。什么可能导致它无法在服务器上运行?当 innerHTML 发生变化时,我可以使用其他方法来触发 myFunction 吗?不使用 DOM 突变事件或观察者?我可以用.length 做点什么吗?最后,我需要它来处理 32 个 uniqe div 元素。
【解决方案2】:

注意:可能不是最好的解释,请添加您的知识以使其更清楚。

如果您愿意使用元素属性,那么有一种方法可以创建自定义元素并根据需要将Observers 添加到属性中。 attributeChangedCallback 是您可以为监听器添加自定义代码的地方。

Custom Elements 属于Web Components,支持ChromeOperaSafari。这是解释有关它们的所有内容的链接。 https://developer.mozilla.org/en-US/docs/Web/Web_Components/Custom_Elements

您可以修改 div 元素的观察者,但我不知道,如果您选择这样做,您可能需要更深入地挖掘。

由于您尝试监听单个元素的 innerHTML,因此最好只创建一个自定义元素,如代码 sn-p 中的那个。

class ObservableDiv extends HTMLElement {
  // Monitor the 'name' attribute for changes.
  static get observedAttributes() {return ['name']; }

  // Respond to attribute changes.
  attributeChangedCallback(attr, oldValue, newValue) {
    if (attr == 'name') {
      this.textContent = `HELLO, ${newValue}`;
    }
  }
}

// Define the new element
customElements.define('observable-div', ObservableDiv);

setTimeout(() => { document.getElementById("change").setAttribute("name", "I CHANGED A LOTTTTTTTTTTT") }, 1000)
<observable-div id="change" name="BEFORE CHANGING"></observable-div>

附言: 这可能根本不是一个正确的答案,但我发布这个是因为这种策略对我来说更好,而不是依赖过去偶尔工作但从未持续工作的子树侦听器。唯一的缺点是它没有很好的浏览器支持。可能已经有一些好的polyfills 可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多