为什么 window 中的“ontouchstart”“被大多数浏览器支持”?

con*_*com 2 javascript dom

我正在重构别人编写的一些代码。有一个函数使用:

!!('ontouchstart' in window)
Run Code Online (Sandbox Code Playgroud)

我已经在其他项目中看到过它:https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js#L40 在 Stackoverflow 答案中: https: //stackoverflow.com/a /4819886/1127635

但它似乎可能比替代方案慢:http://jsperf.com/hasownproperty-vs-in-vs-undefined/12

那么为什么要使用这种可能较慢的替代方案呢?哪些浏览器不支持其他解决方案?

aps*_*ers 5

您的两个替代测试都在某种程度上存在缺陷:

  • window.ontouchstart !== null对非null听众进行测试。测试 的值ontouchstart是一种有风险的方法,因为库或其他代码可能会更改 的值ontouchstart。测试该值是一个不好的方法;最好测试该属性本身是否存在,这将我们带到您提出的下一个测试......

  • window.hasOwnProperty('ontouchstart')测试window对象是否有自己的ontouchstart属性。在某些浏览器中(我刚刚在 Chrome 37 和 IE9 上确认了这一点),window 没有自己的on-event 属性;相反,它们是 的属性window.__proto__。

我们不应该测试某个值(因为之前的代码可能在运行我们的代码之前更改了该值),并且我们无法测试window自己的属性,因为浏览器对 中事件侦听器属性存在位置的实现有所window不同原型链。因此,我们最一致的选择是测试该属性是否存在于window原型链中的任何位置(无论其值如何)。这正是我们对in运算符所做的事情。

当然,如果其他人的代码在我们的测试之前运行,他们可以ontouchstart在原来没有的地方添加一个属性。绝对严格地测试对事件的支持根本不可能,而且这是一件糟糕的事情。

  • @conradk 这很公平;我承认 `=== undefined` 是完全可读的(尽管 `void 0` 作为一个几乎未使用的语言特性“极其”不清楚;请不要这样做)。我不太容易假设“on”属性不能在所有浏览器中设置为“undefined”(如果其他代码首先进入,这又会扰乱您的测试)。此外,我什至不确定旧版浏览器是否始终将“on”属性初始化为“null”。也许他们这样做,但我没有可以测试的浏览器。 (2认同)