【问题标题】:Is there a more efficient way to toggle multiple classes on click than this?有没有比这更有效的方法来切换多个点击类?
【发布时间】:2012-07-22 14:56:38
【问题描述】:

使用 JS 实现这个切换类的更好方法是什么?

这只是在做这样的事情:

当您单击“服务”、“图库”或“客户”时,它会删除下面 div 中的“隐藏”类,并将“隐藏”类添加到同一 div 中的所有其他列表中。

可以在这里看到正在发生的事情的现场演示:http://www.cyberbytesdesign.com/WIP2(它是主要的标题导航)。

这是我正在使用的代码(绝对不是一种有效的方法,因为这不到所有代码的一半,但可以理解)。

<nav>
  <ul class="menu-option-set">
    <li>
      <a href="javascript:;" onmouseup="
        document.getElementById('services').classList.toggle('hidden');
        document.getElementById('gallery').classList.add('hidden');
        document.getElementById('customer').classList.add('hidden');
        ">Services</a>
    </li>
    <li>
       <a href="javascript:;" onmouseup="
         document.getElementById('gallery').classList.toggle('hidden');
         document.getElementById('services').classList.add('hidden');
         document.getElementById('customer').classList.add('hidden'); ">Gallery</a>
    </li>
    <li>
       <a href="javascript:;" onmouseup="
         document.getElementById('gallery').classList.toggle('hidden');
         document.getElementById('services').classList.add('hidden');
         document.getElementById('customer').classList.add('hidden'); ">Customer</a>
    </li>
  </ul>
</nav>
<div id="header-subnav">
  <nav>
    <ul id="services" class="hidden">
      <li <?php echo $bathroom ?>><a href="bathroom">Bathroom</a></li>
      <li <?php echo $kitchen ?>><a href="index.php">Kitchen</a></li>
      <li <?php echo $accessibility ?>><a href="index.php">Accessibility</a></li>
    </ul>
    <ul id="gallery" class="hidden">
      <li <?php echo $photo ?>><a href="gallery.php">Photo Gallery</a></li>
      <li <?php echo $project ?>><a href="project.php">Project Gallery</a></li>
    </ul>
    <ul id="customer" class="hidden">
      <li <?php echo $coupons ?>><a href="coupons.php">Coupons</a></li>
      <li <?php echo $testimonials ?>><a href="testimonials.php">Testimonials</a></li>
    </ul>
  <nav>
</div>

我假设您必须以某种方式执行与使用此类似的操作,但已修改:

$('.menu-option-set a').click(function()
{
    // if clicked item is selected then deselect it
    if ($('#header-subnav').hasClass('hidden'))
    {
        $('#header-subnav').removeClass('hidden');
    }

    // otherwise deselect all and select just this one
    else
    {
        $('.menu-option-set a').removeClass('hidden');
        $('#header-subnav').addClass('hidden');
    }
});

有什么想法吗?

【问题讨论】:

    标签: javascript jquery class toggle


    【解决方案1】:

    少修改版:

    将数据属性添加到主菜单并将其值设置为子菜单的id。

    <nav>
      <ul class="menu-option-set">
        <li>
          <a href="#" data-subid="services">Services</a>
        </li>
        <li>
           <a href="#" data-subid="gallery">Gallery</a>
        </li>
        <li>
           <a href="#" data-subid="customer">Customer</a>
        </li>
      </ul>
    </nav>
    

    然后将事件处理程序附加到主菜单。它隐藏所有子菜单,并显示正确的子菜单。 (而且你不需要“隐藏”类。)

    $(function() {
        $("#header-subnav ul").hide();
        $('.menu-option-set a').on('click', function() {
            var $s = $("#" + $(this).attr('data-subid'));                
            if($s.is(':hidden')) {
                $("#header-subnav ul").hide();
                $s.show();
            } else {
                $s.hide();
            }
        });
    });
    

    ​ 就这样!示例如下:http://jsfiddle.net/dT225/1/

    ...但我个人建议这种风格:

    在每个主菜单旁边放置子菜单。

    <nav id="menu">
      <ul>
        <li>
          <a href="#">Services</a>
          <ul>
            <li <?php echo $bathroom ?>><a href="bathroom">Bathroom</a></li>
            <li <?php echo $kitchen ?>><a href="index.php">Kitchen</a></li>
            <li <?php echo $accessibility ?>><a href="index.php">Accessibility</a></li>
          </ul>
        </li>
        <li>
          <a href="#">Gallery</a>
          <ul>
            <li <?php echo $photo ?>><a href="gallery.php">Photo Gallery</a></li>
            <li <?php echo $project ?>><a href="project.php">Project Gallery</a></li>
          </ul>
        </li>
        <li>
          <a href="#">Customer</a>
          <ul>
            <li <?php echo $coupons ?>><a href="coupons.php">Coupons</a></li>
            <li <?php echo $testimonials ?>><a href="testimonials.php">Testimonials</a></li>
          </ul>
        </li>
      </ul>
    </nav>​​​​​​​​​​​​​
    

    当点击主菜单时,事件处理程序将只显示源元素的下一个元素。

    $(function() {
        $('#menu li ul').hide();
        $('#menu a').on('click', function() {
            var $s = $(this).next();           
            if($s.is(':hidden')) {
                $('#menu li ul').hide();
                $s.show();
            } else {
                $s.hide();
            }
        });
    });
    

    ​我认为它更简单、可维护和语义化。 http://jsfiddle.net/dKtVK/1/

    【讨论】:

    【解决方案2】:

    首先对尝试使用纯 javascript 进行此操作表示赞赏。但是请注意,并非每个浏览器都支持使用 classList 之类的东西 - 您的代码在 IE 中会失败。

    对于您的问题:您几乎自己回答了您的问题。强烈建议不要在元素中使用这些事件属性。而是将其放入(分离的)js(文件)中。这使您的代码干净且可维护。

    所以改为这样写:

    <a class="services" href="javascript:;">Services</a>
    

    然后在 &lt;script&gt; 标签或单独的 JS 文件中添加 eventhandler

    var gallery  = document.getElementById('gallery');
    var services = document.getElementById('services');
    var customer = document.getElementById('customer');
    
    document.querySelector(".services").addEventListener(function(){
        /* Do your stuff here */
        gallery.classList.toggle('hidden');
        /*...and so on...*/
    });
    

    我在这里使用querySelector,因为它和jQuery很相似,所以很多人都熟悉,在IE中支持>=8。但请随意使用适合您的任何东西(并且是浏览器支持所需要的)。

    使用 jQuery(您发布的第二个代码 n-p)使这变得容易得多,并且在所有浏览器中都可以正常工作,因此请随意使用它并为您节省一些工作。

    【讨论】:

    • 关于您在 IE 中失败的 classList 评论,别担心,如果它是 IE (; --> 你可以如果您愿意,请自行检查:P。我知道我的方法很糟糕,我会尝试您的方法,看看我是否有运气!感谢您的快速回复!:)
    • 编辑:您提到我可以使用我的第二个代码 sn-p 来节省一些工作,但是您知道我做错了什么吗?它的工作方式不像我输入的那样好。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 1970-01-01
    相关资源
    最近更新 更多