纯JavaScript方法更新所有列表项的CSS类属性?

9

我希望使用Javascript(而不是jquery)来访问

    列表中的所有项目,并从除了我的选择菜单项之外的所有内容中删除active类。

    这是列表:

    <ul id='flash-menu'>
    <li id="menu1" class='something active'>item 1</li>
    <li id="menu2" class='somethingelse'>item 2</li>
    <li id="menu3" class='somethingelse'>item 3</li>
    </ul>
    

    这是我的JavaScript代码:

    function updateMenu(view_name) {
    var list_items = document.getElementById('flash-menu').childNodes; 
    for (var i=0 ; i<list_items.length ; i++){
            list_items[i].className = list_items[i].className.replace('/\bactive\b/','');
        }
    document.getElementById(view_name).className += " active";
    }
    

    Javascript的最后一行(添加active类)是有效的,但我认为我没有正确访问列表项以从其他项目中删除类。有什么建议吗?-谢谢!

5
感谢你提出要求使用“纯JavaScript”,这个论坛上jQuery已经被过度使用了。 - Q_Mlilo
8个回答

7

首先,你的正则表达式是错误的:

list_items[i].className.replace(/\bactive\b/, '');

注意:在JavaScript中正则表达式不需要引号。稍加修改后的可用版本可在JsFiddle上获取。
此外,在list_items中我会得到一些HTMLTextElement实例。当尝试访问不存在的className属性时,它们会导致循环中断(Fx3.6 / Win7)。您可以通过以下方式之一来避免这种情况:
var list_items = document.getElementById('flash-menu').getElementsByTagName('li');
// Selecting _all_ descendant <li> elements

或者在循环体内读写之前检查 .className 是否存在(示例)。后者可能是最干净的选择,因为它仍然只影响 直接 子元素(您可能在每个 <li> 中有几个级别的 <ul>)。


即,

function updateMenu(view_name) {
    var list_items = document.getElementById('flash-menu').childNodes; 
    for (var i=0, j=list_items.length; i<j; i++){
        var elm = list_items[i];
        if (elm.className) {
            elm.className = elm.className.replace(/\bactive\b/, '');
        }
    }
    document.getElementById(view_name).className += ' active';
}

1

你可以使用 JavaScript 函数 getElementsByTagName:

var listitems = document.getElementsByTagName("li");

这将返回所有列表的数组,并且可以迭代每个列表元素并根据需要进行处理。


@AP257 jensgram以更好的方式使用了相同的函数来解决您的问题。 :) - Ankit Jaiswal

0

这是我的解决方案,可能不是最好的,但对我来说很有效。

window.addEventListener('load', iniciaEventos, false);
function iniciaEventos(e)
{
    var menu = document.querySelectorAll('nav li');
    for(var i = 0; i < menu.length; i++ )
        {
            menu[i].addEventListener('mousedown', clickMenu);
        }
}

function clickMenu()
{
    var menu = document.querySelectorAll('nav li');
    for(var i = 0; i < menu.length; i++)
            menu[i].classList.remove('active');

    this.classList.add('active');
}

0

你可以尝试以下方法:

如果你有多个ul,首先需要获取所有引用,然后逐个处理每个ul:

var uls = document.getElementsByTagName("ul");

    for (uli=0;uli<uls.length;uli++) {

        ul = uls[uli];

        if (ul.nodeName == "UL" && ul.className == "classname") {

            processUL(ul);

        }

    }

proccessUL 的示例可以是:

function processUL(ul) {

    if (!ul.childNodes || ul.childNodes.length == 0) return;

    // Iterate LIs

    for (var itemi=0;itemi<ul.childNodes.length;itemi++) {

        var item = ul.childNodes[itemi];

        if (item.nodeName == "LI") {

            // Iterate things in this LI
 in the case that you need it put your code here 
              .....
        }

    }

}

当然,如果您不需要在LI的子元素之间进行迭代,您也可以使用:item.className = "classname";


0

document.getElementById('flash-menu').childNodes 也会包括空白节点。

function updateMenu(view_name) {

    var list_items = document.getElementById('flash-menu').getElementsByTagName('li'), i; 

    for (i=0 ; i<list_items.length ; i++){
            if (list_items[i].className.indexOf('active') > -1) {
              list_items[i].className = list_items[i].className.replace(/\bactive\b/,'');
            }
        }
    document.getElementById(view_name).className += " active";
}

0

请尝试阅读此链接http://stackoverflow.com/help/deleted-answers,以更好地了解如何“不”回答问题。即:“根本没有回答问题的答案”:**几乎只是一个指向外部网站的链接**。 - Radim Köhler

0

我同意jensgram的观点,你最好这样编码:

list_items[i].className.replace(/\bactive\b/g, '');

在正则表达式字符串后添加 'g'


"g" 是什么意思?正则表达式只在类名上执行。 - Q_Mlilo

0

g代表全局,使用‘/g’可以替换所有匹配的正则表达式,但如果不使用‘/g’,只会替换第一个字符串。 就像这样:

var test = "testeetest" ;
alert(test.replace(/e/,"")) ;//结果 : tsteetest 但使用'g' var test = "testeetest" ;
alert(test.replace(/e/g,"")) ;//结果 : tsttst


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接