使用 JavaScript 添加类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17944843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
add class with JavaScript
提问by vincentieo
I am writing some vanilla JavaScript to create a nice navigation menu. I am stuck on adding an active class.
我正在编写一些普通的 JavaScript 来创建一个漂亮的导航菜单。我坚持添加一个活动类。
I am getting elements by class name NOT by id. The below code works if substituted with id, however, I need it to apply to more than one element.
我按类名而不是 id 获取元素。如果用 id 代替,下面的代码有效,但是,我需要将它应用于多个元素。
HTML
HTML
<img class="navButton" id="topArrow" src="images/arrows/top.png" />
<img class="navButton" id="rightArrow" src="images/arrows/right.png" />
JS
JS
var button = document.getElementsByClassName("navButton");
button.onmouseover = function() {
button.setAttribute("class", "active");
button.setAttribute("src", "images/arrows/top_o.png");
}
No answers containing jQuery please.
请没有包含 jQuery 的答案。
回答by mohkhan
document.getElementsByClassName
returns a node list. So you'll have to iterate over the list and bind the event to individual elements. Like this...
document.getElementsByClassName
返回一个节点列表。因此,您必须遍历列表并将事件绑定到单个元素。像这样...
var buttons = document.getElementsByClassName("navButton");
for(var i = 0; i < buttons.length; ++i){
buttons[i].onmouseover = function() {
this.setAttribute("class", "active");
this.setAttribute("src", "images/arrows/top_o.png");
}
}
回答by Elias Van Ootegem
In your snippet, button
is an instance of NodeList
, to which you can't attach an event listener directly, nor can you change the elements' className
properties directly.
Your best bet is to delegate the event:
在您的代码段中,button
是 的一个实例NodeList
,您不能直接将事件侦听器附加到该实例,也不能直接更改元素的className
属性。
最好的办法是委托事件:
document.body.addEventListener('mouseover',function(e)
{
e = e || window.event;
var target = e.target || e.srcElement;
if (target.tagName.toLowerCase() === 'img' && target.className.match(/\bnavButton\b/))
{
target.className += ' active';//set class
}
},false);
Of course, my guess is that the active
class needs to be removed once the mouseout
event fires, you might consider using a second delegator for that, but you couldjust aswell attach an event handler to the one element that has the active
class:
当然,我的猜测是active
一旦mouseout
事件触发就需要删除该类,您可能会考虑为此使用第二个委托人,但您也可以将事件处理程序附加到具有active
该类的一个元素:
document.body.addEventListener('mouseover',function(e)
{
e = e || window.event;
var oldSrc, target = e.target || e.srcElement;
if (target.tagName.toLowerCase() === 'img' && target.className.match(/\bnavButton\b/))
{
target.className += ' active';//set class
oldSrc = target.getAttribute('src');
target.setAttribute('src', 'images/arrows/top_o.png');
target.onmouseout = function()
{
target.onmouseout = null;//remove this event handler, we don't need it anymore
target.className = target.className.replace(/\bactive\b/,'').trim();
target.setAttribute('src', oldSrc);
};
}
},false);
There is some room for improvements, with this code, but I'm not going to have all the fun here ;-).
这段代码还有一些改进的空间,但我不会在这里享受所有的乐趣;-)。
Check the fiddle here
检查小提琴here
回答by Aleksandr Albert
Here is a method adapted from Jquery 2.1.1 that take a dom element instead of a jquery object (so jquery is not needed). Includes type checks and regex expressions:
这是一种改编自 Jquery 2.1.1 的方法,它采用 dom 元素而不是 jquery 对象(因此不需要 jquery)。包括类型检查和正则表达式:
function addClass(element, value) {
// Regex terms
var rclass = /[\t\r\n\f]/g,
rnotwhite = (/\S+/g);
var classes,
cur,
curClass,
finalValue,
proceed = typeof value === "string" && value;
if (!proceed) return element;
classes = (value || "").match(rnotwhite) || [];
cur = element.nodeType === 1
&& (element.className
? (" " + element.className + " ").replace(rclass, " ")
: " "
);
if (!cur) return element;
var j = 0;
while ((curClass = classes[j++])) {
if (cur.indexOf(" " + curClass + " ") < 0) {
cur += curClass + " ";
}
}
// only assign if different to avoid unneeded rendering.
finalValue = cur.trim();
if (element.className !== finalValue) {
element.className = finalValue;
}
return element;
};
回答by Yoni
Simply add a class name to the beginning of the funciton and the 2nd and 3rd arguments are optional and the magic is done for you!
只需在函数的开头添加一个类名,第二个和第三个参数是可选的,魔术就为您完成了!
function getElementsByClass(searchClass, node, tag) {
var classElements = new Array();
if (node == null)
node = document;
if (tag == null)
tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp('(^|\\s)' + searchClass + '(\\s|$)');
for (i = 0, j = 0; i < elsLen; i++) {
if (pattern.test(els[i].className)) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
回答by ketan
There is build in forEach loop for array in ECMAScript 5th Edition.
在 ECMAScript 第 5 版中为数组内置了 forEach 循环。
var buttons = document.getElementsByClassName("navButton");
Array.prototype.forEach.call(buttons,function(button) {
button.setAttribute("class", "active");
button.setAttribute("src", "images/arrows/top_o.png");
});
回答by ojrask
I like to use a custom "foreach" function of sorts for these kinds of things:
我喜欢使用自定义的“foreach”函数来处理这些事情:
function Each( objs, func )
{
if ( objs.length ) for ( var i = 0, ol = objs.length, v = objs[ 0 ]; i < ol && func( v, i ) !== false; v = objs[ ++i ] );
else for ( var p in objs ) if ( func( objs[ p ], p ) === false ) break;
}
(Can't remember where I found the above function, but it has been quite useful.)
(不记得我在哪里找到了上述功能,但它非常有用。)
Then after fetching your objects (to elements
in this example) just do
然后在获取你的对象(elements
在这个例子中)之后就做
Each( elements, function( element )
{
element.addEventListener( "mouseover", function()
{
element.classList.add( "active" );
//element.setAttribute( "class", "active" );
element.setAttribute( "src", "newsource" );
});
// Remove class and new src after "mouseover" ends, if you wish.
element.addEventListener( "mouseout", function()
{
element.classList.remove( "active" );
element.setAttribute( "src", "originalsource" );
});
});
classList
is a simple way for handling elements' classes. Just needs a shim for a few browsers. If you must use setAttribute
you must remember that whatever is set with it willoverwrite the previous values.
classList
是一种处理元素类的简单方法。只需要一些浏览器的垫片。如果您必须使用,setAttribute
您必须记住,用它设置的任何内容都会覆盖以前的值。
EDIT: Forgot to mention that you need to use attachEvent
instead of addEventListener
on some IE versions. Test with if ( document.addEventListener ) {...}
.
编辑:忘记提及您需要在某些 IE 版本上使用attachEvent
而不是使用addEventListener
。用 测试if ( document.addEventListener ) {...}
。
回答by Arda
getElementsByClassName()
returns HTMLCollection so you could try this
getElementsByClassName()
返回 HTMLCollection 所以你可以试试这个
var button = document.getElementsByClassName("navButton")[0];
Edit
编辑
var buttons = document.getElementsByClassName("navButton");
for(i=0;buttons.length;i++){
buttons[i].onmouseover = function(){
this.className += ' active' //add class
this.setAttribute("src", "images/arrows/top_o.png");
}
}