当网页添加内容时,我需要触发一个动作。更新可能是不同的性质(例如AJAX、延迟脚本、用户操作等),并且不在我的控制范围内。
我想使用DOM突变事件,但并非所有浏览器都支持。是否有跨浏览器库可提供备用计划?
此外,我想知道Internet Explorer 9是否支持这些DOM突变事件。
谢谢!
当网页添加内容时,我需要触发一个动作。更新可能是不同的性质(例如AJAX、延迟脚本、用户操作等),并且不在我的控制范围内。
我想使用DOM突变事件,但并非所有浏览器都支持。是否有跨浏览器库可提供备用计划?
此外,我想知道Internet Explorer 9是否支持这些DOM突变事件。
谢谢!
有两种方法可以做到这一点...
第一种方法是拍摄 DOM 快照(var snap = document.body
),将其与 100 毫秒后的 DOM 进行比较,然后再将 snap
重置为 body。我会让你自己想象如何进行比较:迭代似乎是常见的答案。这不太美观。
另一种选择是在您创建添加/删除应用程序元素的任何函数中都有一个特殊的函数。此函数将仅遍历您添加(或销毁)的元素并查找匹配项。
/* Shim matchesSelector */
if (!Element.prototype.matchesSelector) {
Element.prototype.matchesSelector =
Element.prototype.matches ||
Element.prototype.webkitMatchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector;
}
function addingToDom(elm){
/* Whichever method you want to use to map selectors to functions */
var callbacks = array(['.class', fn-reference1], ['#id', fn-reference2], ['div', fn-reference3]);
/* go through all the elements you're adding */
for (var i = 0; i<elm.length; ++i){
/* go through all the selectors you're matching against */
for (var k = 0; k<callbacks.length ++k){
if(elm[i].matchesSelector(callbacks[k][0])){
/* call function with element passed as parameter */
callbacks[k][1](elm[i]);
}
}
}
}
这可能不是完美的,但它应该能让你知道该往哪个方向前进。调用此函数(addingToDom),将刚刚添加的元素作为参数传递。创建一个类似的函数来删除元素(或者同一个函数,但条件是一个单独的回调数组)。
这是我正在使用的一段当前(庞大而混乱的)代码的推断,用于测试一些想法。我已经使用了这个 shim 测试了匹配选择器,甚至可以追溯到 ie7,它似乎运行得非常好!
我考虑过,但没有深入研究,元素可能具有某种参数,可以设置为在添加时调用的函数,并将自身作为参数传递。但是,那可能太牵强了。
嗯... 这里有一个判断元素是否添加的想法: 给页面上的每个元素附加一个类,然后使用查询找到每个没有该类的元素querySelectorAll(':not(.myclass)')
,然后循环遍历这些元素。
你仍然需要定期运行它,但是querySelectorAll由于它是本机浏览器所以很快,并且如果它返回“空”(false
? null
? 不太清楚),那么你就不做任何事情,这样应该是最小的开销。
我刚刚发现了一个依赖于CSS事件的有趣的黑客技巧:
http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/
根据作者的说法,这在IE10、Firefox 5+、Chrome 3+、Opera 12、Android 2.0+、Safari 4+以及几乎所有版本的iPhone Safari中都可以使用。
您可以通过设置一个函数并使用JSONP进行AJAX请求来调用该函数,从而轻松触发操作。同样的函数也可以在用户操作期间被调用。