Both of your alternative tests are flawed in some way:
window.ontouchstart !== null
tests for a non-null
listener. Testing the value of ontouchstart
is a risky approach because libraries or other code might change the value of ontouchstart
. Testing the value is a bad approach; it would be much better to test for the existence of the property itself, which brings us to your next proposed test...
window.hasOwnProperty('ontouchstart')
tests if the window
object has its own ontouchstart
property. In some browsers (I've just confirmed this on Chrome 37 and IE9), window
doesn't have its own on
-event properties; instead, they are properties of window.__proto__
.
We shouldn't test for a value (because previous code may have changed the value before we run our code) and we can't test for window
's own property, because browser differ in their implementation of where event listener properties exist in window
's prototype chain. So, our most consistent option is to test whether the property exists (regardless of value) anywhere in window
's prototype chain. This is exactly what we do with the in
operator.
Of course, if someone else's code runs before our test, they could add an ontouchstart
property where there originally wasn't one. Testing support for events with absolute rigor simply isn't possible and it's an awful business.