我有一个javascript插件,可以在DOM中搜索以类名“tracking”开头的任何元素,并将click事件监听器(或其他类型的监听器,如果指定)添加到该元素。这个想法是每次该事件发生在该元素上时,它运行一个javascript函数,将数据发送到我们的流量服务器。这是代码的样子。
// Once the page is completed loaded
window.mmload(function() {
// Get the container object
obj = document.getElementById(name);
if ( obj.length < 0 )
throw ("The Id passed into the tracker does not exist ("+name+")");
// Find all the elements belonging to the tracking class
var trackingClass = new RegExp( /tracking\[[a-zA-Z0-9\.\-_]+\]/g );
var myElements = getElementsByRegex( trackingClass, obj );
//For each of those elements...
for( var i in myElements ) {
var elm = myElements[i];
var method = elm.className.match( /tracking\[[a-zA-Z0-9\.\-_]+\]/ )[0].split('[')[1].replace(']','').split('.')[2];
method = typeof( method ) == 'undefined' ? 'click' : method;
// Add a click event listener
myElements[i].addEventListener( method, function(e){
// Get the element, the link (if any), and the args of the event
var link = elm.getAttribute('href') == null ? "" : elm.getAttribute('href');
var args = elm.className.match( /tracking\[[a-zA-Z0-9\.\-_]+\]/ )[0].split('[')[1].replace(']','').split('.');
// If a link existed, pause it, for now
if ( link != '' )
e.preventDefault();
// Track the event
eventTracker( args[0], args[1], ( method == 'click' ? 'redirect' : 'default' ), link );
return false;
}, true);
}
});
现在,一旦窗口完全加载,我就会运行这些代码(window.mmload()是我为追加window.onload事件而做的一个函数)。但是,有时我可能需要再次运行此函数,因为我通过带有此类名称的javascript向DOM添加了新元素,我也想跟踪它们。
我的初始解决方案是使用setInterval运行此函数,每隔几毫秒或第二次或任何最有意义的方式检查DOM。但是,我担心如果我采用这种方法可能会减慢网站速度,特别是因为这是在智能手机的移动网站上运行。如果我经常搜索DOM,我不确定我可能会遇到什么样的性能损失。
我想到的另一种方法是在将可追踪元素添加到DOM之后简单地调用该函数。这可能是处理它的最有效方式。然而,我与之合作的人,非常聪明的人,都是网页设计师,他们不经常思考也不能很好地理解代码。所以我可以做得越简单越好。这就是我喜欢setInterval方法的原因,因为它们不需要额外的东西。但如果它明显减慢了网站的速度,我可能不得不采取另一种方法。
答案 0 :(得分:1)
您应该考虑甚至委派。
您只需将一个事件侦听器添加到文档根目录,然后检查事件源自的元素类(event.target
)。如果你想包括来自后代的点击,你必须从目标遍历DOM,并检查是否有任何祖先包含该类。
我看到两个主要优点:
缺点:
更多信息:
事件处理程序获取event
对象作为第一个参数。此对象包含several properties,which element the event originated form。
E.g。获取目标元素:
var element = event.target || event.srcElement;
这将是一个DOM元素,您可以通过element.className
访问这些类。
因此,您的事件监听器可能如下所示(请注意IE uses another method to attach event listeners且事件对象未通过,但可通过window.event
获得):
function handler(event) {
event = event || window.event;
var target = event.target || event.srcElement;
if(target.className.match(/tracking\[[a-zA-Z0-9\.\-_]+\]/g) {
// do your stuff
}
}
if(document.addEventListener) {
document.addEventListener('click', handler, false);
}
else {
document.attachEvent('onclick', handler);
}
但正如我所说,这会错过那些无法冒泡的事件。至少在遵循W3C模型的浏览器中(所以不是IE),您可以通过将最后一个参数设置为true
来处理capture phase中的事件:
document.addEventListener('click', handler, true);
答案 1 :(得分:0)
如果您可以在没有IE的情况下生活,那么您可以为窗口/文档/ dom元素挂接change
事件。只需在文档级别挂钩,即可在页面中更改某些内容(插入,删除,更改内容)。我相信事件的上下文包含了已经改变的内容,因此找到任何新的可跟踪元素并将间谍代码附加到它上面应该是相当简单的。
答案 2 :(得分:0)
第三种选择是编写一种操作元素的innerHTML的方法。在该方法结束时,只需调用刷新所有内容的函数。
示例:
var setHtml = function(element, newHtml){
element.innerhtml = newHtml;
yourRefreshFunction();
}
显然,这需要您的Web开发人员使用此方法来更新dom。而且你必须为任何比简单的html编辑更复杂的事情做这件事。但这给了你这个想法。
希望有所帮助!