用JavaScript添加类
我正在写一些香草JavaScript来创build一个不错的导航菜单。 我坚持添加一个活跃的类。
我通过类名获取元素不是由id。 下面的代码工作,如果用id代替,但是,我需要它适用于多个元素。
HTML
<img class="navButton" id="topArrow" src="images/arrows/top.png" /> <img class="navButton" id="rightArrow" src="images/arrows/right.png" />
JS
var button = document.getElementsByClassName("navButton"); button.onmouseover = function() { button.setAttribute("class", "active"); button.setAttribute("src", "images/arrows/top_o.png"); }
请不要包含jQuery的答案。
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"); } }
在你的片段中, button
是NodeList
一个实例,你不能直接附加一个事件监听器,也不能直接改变元素的className
属性。
你最好的select是委托这个事件:
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);
当然,我的猜测是,一旦mouseout
事件触发, active
类需要被移除,你可以考虑使用第二个委托,但是你也可以附加一个事件处理函数到一个具有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);
这个代码有一些改进的空间,但是我不会在这里获得所有的乐趣;-)。
在这里检查小提琴
这里是一个从Jquery 2.1.1改编的方法,而不是一个jQuery对象(所以不需要jquery)。 包括types检查和正则expression式:
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; };
getElementsByClassName()
返回HTMLCollection,所以你可以试试这个
var button = document.getElementsByClassName("navButton")[0];
编辑
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"); } }
在ECMAScript第5版中为forEach循环创build了数组。
var buttons = document.getElementsByClassName("navButton"); Array.prototype.forEach.call(buttons,function(button) { button.setAttribute("class", "active"); button.setAttribute("src", "images/arrows/top_o.png"); });
我喜欢使用自定义的“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; }
(不记得我在哪里find了上面的函数,但是它非常有用。)
然后提取你的对象(在这个例子中的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
是处理元素类的简单方法。 只需要几个浏览器的垫片。 如果您必须使用setAttribute
,则必须记住,无论使用setAttribute
进行设置,它都会覆盖之前的值。
编辑:忘了提及,你需要在一些IE版本上使用attachEvent
而不是addEventListener
。 用if ( document.addEventListener ) {...}
。
只需在function的开头添加一个类名,第二个和第三个参数是可选的,魔术就是为你完成的!
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; }