细说浏览器特性检测(2)-通用事件检测

2020-05-17 06:19:02易采站长站整理

supported = typeof element[name] == ‘function’;
element.removeAttribute(name);
}
//添加到缓存
cache[name] = supported;
return supported;
};
})();
Mutation Event

Mutation Event是由DOM Level 2制定的一类特殊的事件,这些事件在某个元素为根的DOM树结构发生变化时触发,可以在这里看到具体的事件列表。


遗憾的是hasEvent函数无法检测到Mutation Event,因此对于此类事件,需要另一种较为复杂的事件检测方案。


从Mutation Event的列表中可以发现,此类事件的特点在于当DOM树结构发生变化时才会被触发,因此可以使用下面这套逻辑去检测:

准备一个标记位,默认为false。
创建出一个DOM树结构。
注册一个Mutation Event。
通过一定手段让这个DOM树变化,从而触发注册的事件。
在事件处理函数中,将标记位设为true。
返回标记位。

具体的实现代码可以如下:

function hasMutationEvent(name, tag, change) {
var element = document.createElement(tag),
supported = false;
function handler() {
supported = true;
};
//IE9开始支持addEventListener,因此只有IE6-8没有这个函数
//但是IE6-8已经确定不支持Mutation Event,所以有这个判断
if (!element.addEventListener) {
return false;
}
element.addEventListener(name, handler, false);
change(element);
element.removeEventListener(name, handler, false);
return supported;
};

例如需要检测DOMAttrModified事件是否存在,只需要用以下代码:

var isDOMAttrModifiedSupported =
hasMutationEvent(‘DOMAttrModified’, ‘div’, function (div) { div.id = ‘new’; });

对于其他事件的检测,同样只需要制作出一个特定的change函数即可。


DOMContentLoaded

这个事件在文档加载完成时触发,但不需要等待图片等资源下载,多数Javascript框架的document.ready都会试图使用这个事件。


无论是hasEvent函数还是hasMutationEvent函数都无法检测到这个事件,但是问题不大,因为:

这事件和onload一样,页面的生命周期中只会触发一次,不会频繁使用。
所有支持addEventListener的浏览器都支持这个事件(包括IE9),因此判断简单。

所以这个事件被排除在了本文讨论范围之外,具体的可以查看各框架的document.ready函数的实现方式。


相关资源

Detecting event support without browser sniffing为本文提供了大量的思路。
Diego Perini’s NWMatcher提供了Mutation Event检测的思路。
点此查看hasEvent和hasMutationEvent的源码。

哪位无聊就把所有的Mutation Event的检测函数写出来吧……