admin管理员组文章数量:1355056
I want to bind a single function to multiple events using pure Javascript.
In jQuery I would use:
$('.className').click(function(e){ //do stuff });
So using pure JS I tried:
document.getElementsByClassName('className').onclick = function(e){ //do stuff };
Which doesn't work, because getElementsByClassName
returns an array, not a DOM object.
I can loop through the array, but this seems overly verbose and like it shouldn't be necessary:
var topBars = document.getElementsByClassName('className');
for(var i = 0; i < topBars.length; i++){
topBars[i].onclick = function(e){ //do stuff };
}
Is there a standard way to acplish this with pure Javascript?
I want to bind a single function to multiple events using pure Javascript.
In jQuery I would use:
$('.className').click(function(e){ //do stuff });
So using pure JS I tried:
document.getElementsByClassName('className').onclick = function(e){ //do stuff };
Which doesn't work, because getElementsByClassName
returns an array, not a DOM object.
I can loop through the array, but this seems overly verbose and like it shouldn't be necessary:
var topBars = document.getElementsByClassName('className');
for(var i = 0; i < topBars.length; i++){
topBars[i].onclick = function(e){ //do stuff };
}
Is there a standard way to acplish this with pure Javascript?
Share Improve this question asked Jan 11, 2015 at 22:39 James G.James G. 2,9044 gold badges29 silver badges55 bronze badges 6- 1 jQuery does the same looping .... only it does it under the hood – charlietfl Commented Jan 11, 2015 at 22:41
-
1
This is exactly the way jQuery does it. However you can use
Array.map.call()
. But it's not really slower/faster. – Mouser Commented Jan 11, 2015 at 22:41 -
It could be
$(document).on('click', '.className', ...)
that literally attaches only a single handler. The same could be done in pure JS (using event bubbling) – zerkms Commented Jan 11, 2015 at 22:42 - You can use event delegation on the closest parent. – elclanrs Commented Jan 11, 2015 at 22:42
-
You could also extend the prototype of the
NodeList
, or `HTMLCollection’, but there would still be looping taking place, otherwise (as noted already) there's delegation. – David Thomas Commented Jan 11, 2015 at 22:43
3 Answers
Reset to default 10You could add the event handler to the parent element, and then determine whether one of the children elements with the desired classname is clicked:
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
if ((' ' + e.target.className + ' ').indexOf(' item ') !== -1) {
// add logic here
console.log(e.target);
}
});
Example Here
or...
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
Array.prototype.forEach.call(parent.querySelectorAll('.item'), function (el) {
if (el === e.target) {
// add logic here
console.log(e.target);
}
});
});
Example Here
The above snippets will only work when you are clicking on the element with the specified class. In other words, it won't work if you click on that given element's child. To work around that, you could use the following:
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
var target = e.target; // Clicked element
while (target && target.parentNode !== parent) {
target = target.parentNode; // If the clicked element isn't a direct child
if (!target) { return; } // If element doesn't exist
}
if ((' ' + target.className + ' ').indexOf(' item ') !== -1){
// add logic here
console.log(target);
}
});
Alternative Example
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
var target = e.target; // Clicked element
while (target && target.parentNode !== parent) {
target = target.parentNode; // If the clicked element isn't a direct child
if (!target) { return; } // If element doesn't exist
}
Array.prototype.forEach.call(parent.querySelectorAll('.item'), function (el) {
if (el === target) {
// add logic here
console.log(target);
}
});
});
Example Here
As a hack, where the DOM is implemented using a prototype inheritance model (most browsers but not all), you can add an iterator to the NodeList constructor:
if (NodeList && NodeList.prototype && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function(callback, thisArg) {
Array.prototype.forEach.call(this, callback, thisArg)
}
}
Then:
document.getElementsByClassName('item').forEach(function(el){
el.addEventListener('click', someFn, false);
})
or
document.querySelectorAll('.item').forEach(function(el){
el.addEventListener('click', someFn, false);
})
Of course you shouldn't do this in production on the web (don't mess with host objects and all that), but wouldn't it be nice if it was OK? Or iterators were added to DOM lists and collections?
var elems = document.querySelectorAll('.className');
var values = Array.prototype.map.call(elems, function(obj) {
return obj.onclick = function(e){ //do stuff };
});
This (adapted example from MDN) is how you could do it without a traditional loop.
本文标签: domIs there a pure Javascript way to apply one function to multiple element39s eventsStack Overflow
版权声明:本文标题:dom - Is there a pure Javascript way to apply one function to multiple element's events? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743985634a2571264.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论