【问题标题】:JQuery instruction can't toggle class on only one targetJQuery 指令不能只在一个目标上切换类
【发布时间】:2014-11-28 12:22:03
【问题描述】:

我今天在我的一个 JQuery 脚本上运行了一个神秘的错误。 我有一个像这样的简单 HTML 页面:

<section id="article" class="col-xs col-md col-lg-10 col-lg-offset-1">
    <nav id="page_menu">
        <ol>
            <li class="page_menu_selected"><a href="#9">Community</a></li>
            <li class="page_menu_unselected"><a href="#42">irc channels</a></li>
            <li class="page_menu_unselected"><a href="#40">mailing lists</a></li>
            <li class="page_menu_unselected"><a href="#38">q&amp;a section</a></li>
        </ol>
    </nav>
    <article class="show" id="9">
    <h3>TITLE:</h3>
        <p>Blablablba 01</p>
    </article>
    <article class="hidden" id="42"></article>
    <article class="hidden" id="40"></article>
    <article class="hidden" id="38">
        <h3>TITLE:</h3>
            <p>BLABLABLABLA 02</p>
    </article>
</section>

和JQuery相关的脚本:

$( document ).ready(function(){
    $( "li.page_menu_unselected" ).click(
        function(){
            $("li.page_menu_selected").toggleClass("page_menu_unselected page_menu_selected")
            $( this ).toggleClass("page_menu_unselected page_menu_selected");
    });
});

乍一看,当我开始测试我的代码时,似乎一切正常,因为我点击了未选择的元素并且类切换正确,即使是选择了类值的那个。

这个具有初始“选定”类值的列表项元素是链接 id 为 9 的列表。

问题是当我点击这个列表元素时,它不会切换回它的初始类,与所有其他列表项不同。

如果我在页面加载后尝试将我粘贴的代码推送到 chrome 控制台并尝试使用它,TADA 它就像一个魅力!

我认为这是一个 DOM 问题,但无法弄清楚它在哪里。

【问题讨论】:

  • 提示:避免ids 以数字开头。不推荐。
  • 您的代码中缺少分号。
  • @MelanciaUK 只是一个复制/粘贴问题 ;-) 但感谢您回答有关带数字的 id 的问题,不幸的是,我必须使用它们,因为该页面部分由 Wordpress 生成:D
  • 在同一个 script 块上,您可以循环遍历这些元素并修复它们的 ids,方法是在它们前面加上一些 string 值。
  • @MelanciaUK,不,我不能,因为 id 由 wordpress 函数返回,并且来自没有任何文本引用但 id 和/或 menu_order int 值的特定页面。跨度>

标签: jquery html css dom


【解决方案1】:

您应该在这里使用delegation,因为您的第一个项目在第一次加载时不会附加点击事件处理程序(它的class - page_menu_selected - 与@987654326 中使用的不同@ 选择器 - page_menu_unselected)。

使用delegation,您将保证将来添加到DOM 中的任何适合jQuery 选择器的元素都将以相同的方式被选中:

$(function () {
    $(document).on('click', 'li.page_menu_unselected', function () {                 
        $('li.page_menu_selected').toggleClass('page_menu_unselected page_menu_selected');
        $(this).toggleClass('page_menu_unselected page_menu_selected');
    });
});

Demo

jQuery .on() - Direct and delegated events

【讨论】:

  • Arff...我现在感觉很愚蠢,因为答案是如此明显和逻辑...这解释了为什么我的复制/粘贴/操作正在工作,因为它会再次扫描整个 DOM第一项已经具有适当的价值。非常感谢指出我的错误。哦,谢谢 .on() 委托功能,我会用它来代替。
【解决方案2】:

页面加载时会发生什么,它会立即找到所有li.page_menu_unselected,然后将事件附加到它们。当这些类发生变化时,附加的事件记录器会失败,因为它不再存在。使用delegate() 可以解决这个问题。

$( document ).ready(function(){
    $(document).delegate("li.page_menu_unselected", "click", function(){
        $("li.page_menu_selected").toggleClass("page_menu_unselected page_menu_selected")
        $( this ).toggleClass("page_menu_unselected page_menu_selected");
    });
});

【讨论】:

  • jQuery delegated 已弃用,在 jQuery 1.7+ 中使用 on
  • 虽然没有正式弃用,但 delegate() 从 1.7 开始已被 on() 方法取代。
猜你喜欢
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
相关资源
最近更新 更多