Here’s some futuristic JavaScript that does exactly the same thing:
var key = "some_key";
var selector = "#my_input, input[name=my_input], .someInputs";
document.addEventListener('change', function (e) {
if (e.target.matches(selector)) {
doSomething(key, e.target.value);
}
});
However, several browsers only support it with a prefix, so it’ll be closer to this:
var matches = (function () {
var names = ['matches', 'matchesSelector', 'mozMatchesSelector', 'webkitMatchesSelector', 'msMatchesSelector'];
for (var i = 0; i < names.length; i++) {
var name = names[i];
if (name in HTMLElement.prototype) {
return HTMLElement.prototype[name];
}
}
return null;
})();
var key = "some_key";
var selector = "#my_input, input[name=my_input], .someInputs";
document.addEventListener('change', function (e) {
if (matches.call(e.target, selector)) {
doSomething(key, e.target.value);
}
});
Assuming the selector isn’t dynamic and you need delegation, you can still do the verbose, manual check:
var key = "some_key";
document.addEventListener('change', function (e) {
var target = e.target;
if (target.id === 'my_input' ||
target.nodeName === 'INPUT' && target.name === 'my_input' ||
(' ' + target.className + ' ').indexOf(' someInputs ') !== -1) {
doSomething(key, target.value);
}
}, false);
As @T.J. Crowder points out, although this works for input elements, you’ll need to check an element’s parents in many cases. Here’s some even more futuristic JavaScript to accomplish the task:
function* ascend(element) {
do {
yield element;
} while ((element = element.parentNode));
}
var key = "some_key";
var selector = "#my_input, input[name=my_input], .someInputs";
document.addEventListener('change', function (e) {
var match = Array.from(ascend(e.target)).find(x => x.matches(selector));
if (match) {
doSomething(key, match.value);
}
});
If you smashed Firefox Nightly and Chrome together, this would work in that browser. We don’t have that, but feel free to shim Array.prototype.find
!