0

我正在创建一个投资组合网站,并且正在努力使用 JQuery 选择合适的元素。.inner我的目标是在单击.outer(类别)项目时显示/隐藏(任务)项目。当菜单展开时,我有.arrows 旋转。

这是一个类似的问题,以及随附的jsfiddle

感谢Tats_innit的原始答案。

我有这个 HTML:

<li class="outer" hook="01">
    <div class="arrow"></div>
    Category 1
</li>
<li class="inner" id="menu-01">
    Task 1
</li>
<li class="inner" id="menu-01">
    Task 2
</li>
<li class="inner" id="menu-01">
    Task 3
</li>

<li class="outer" hook="02">
    <div class="arrow"></div>
    Category 2
</li>
<li class="inner" id="menu-02">
    Task 1
</li>
    <li class="inner" id="menu-02">
    Task 2
</li>
    <li class="inner" id="menu-02">
    Task 3
</li>

而这个jQuery:

$(document).ready(function(){
        $('.outer').click(function(){
            var elem = $('#menu-'+$(this).attr('hook')),
                arrow = $(this).children('.arrow')

            if (!elem.is(':visible'))  {
                arrow.rotate({animateTo:90, duration:128});
            } else {
                arrow.rotate({animateTo:0, duration:128});
            }
            elem.slideToggle('128ms', function() {
            });

        return false;
    });
});

我知道我需要更改var elem = $('#menu-'+$(this).attr('hook'))但我不确定如何显示. 我没有嵌套元素,因为我有一个类的悬停状态。.inner.innerbackground-color: #f1f1f1;.outer

4

4 回答 4

4

这个问题是可以解决的,但是你的方法一开始就有很多问题,所以我想改为改变这些。然后解决问题。

  1. id属性是唯一的。同一页面中不能有多个相同id的元素;出于这个原因,使用class.
  2. hook不是有效的 HTML 属性;虽然这确实不会伤害您并且浏览器很可能会忽略它,但我宁愿看到它标准化,data-hook就像您希望的那样。这也将允许您使用标准 API。
  3. 你应该嵌套在.inner里面,.outer因为它在语义上是有意义的,它会优雅地降级并且对于屏幕阅读器也是可以理解的。您提到的关于悬停背景的问题,我认为可以通过一些好的 CSS 轻松解决:虽然我不了解具体问题,所以我不能说。

但事实是,使用嵌套您可能不需要大多数这些 id、类和随机数据属性(除非显然您需要它们而不是仅仅打开一个列表)。

之后,您的HTML将如下所示:

<ul>
    <li class="outer">
         <div class="arrow"></div>
         Category 1
         <ul>
             <li>
                 Task 1
             </li>
             <li>
                 Task 2
             </li>
             <li>
                 Task 3
             </li>
         </ul>
    </li>
    <li class="outer">
         <div class="arrow"></div>
         Category 1
         <ul>
             <li>
                 Task 1
             </li>
             <li>
                 Task 2
             </li>
             <li>
                 Task 3
             </li>
         </ul>
    </li>
</ul>

你喜欢这样的jQuery :

$('.outer').click(function(){
    var elem  = $(this).children('ul'),
        arrow = $(this).children('.arrow')

    if (!elem.is(':visible'))  {
        arrow.rotate({animateTo:90, duration:128});
    } else {
        arrow.rotate({animateTo:0, duration:128});
    }
    elem.slideToggle('128ms', function() {
    });

    return false;
});

最后一点,.arrow这不是一个非常语义化的元素,因为它甚至不用于激活动画(点击绑定到 the li.outer)我会完全删除它,而是使用 a 来实现相同的效果pseudo-elementli并且可能旋转它使用 CSS3。

编辑

我不确定您为什么无法使其正常运行;尽管您告诉我您很欣赏有关嵌套的评论,但您的小提琴没有使用正确的嵌套。

无论如何,我用我在这里给你的建议为你举了一个例子,基本上我只是逐字复制了我在这里写的代码。不过,我做了一些调整:比如实现 CSS 伪元素并去掉那个div.arrow元素,老实说,这看起来很糟糕。

显然只是一个例子,但它显示了应该如何处理这个问题。希望它能解决你的疑惑:

Working example

于 2013-09-07T19:32:38.073 回答
1
<script>
$(document).ready(function(){
    $('li.inner').hide();
    $('.outer').click(function()
    {
        var elem = $(this).attr('hook');
        $('li.inner').hide();
        $(".menu-"+elem).toggle();
    });
});
</script>
<ul>
<li class="outer" hook="01">
<div class="arrow"></div>
Category 1
</li>
<li class="inner menu-01">
Task 1
</li>
<li class="inner menu-01">
Task 2
</li>
<li class="inner menu-01">
Task 3
</li>

<li class="outer" hook="02">
<div class="arrow"></div>
Category 2
</li>
<li class="inner menu-02">
Task 1
</li>
<li class="inner menu-02">
Task 2
</li>
<li class="inner menu-02">
Task 3
</li>
</ul>

首先将 li id 更改为 class 因为 2 li 没有相同的 id

于 2013-09-07T19:28:25.417 回答
1

您可以将一组outer和嵌套inner到一个div

<div>
    <li class="outer">
        <div class="arrow"></div>
        Category 1
    </li>
    <li class="inner">
        Task 1
    </li>
    <li class="inner">
        Task 2
    </li>
    <li class="inner">
        Task 3
    </li>
</div>

那么你的js代码就像

$('.outer').click(function(){
    var elem = $(this).siblings('.inner'),
        arrow = $(this).children('.arrow')

    if (!elem.is(':visible'))  {
        arrow.rotate({animateTo:90, duration:128});
    } else {
        arrow.rotate({animateTo:0, duration:128});
    }
    elem.slideToggle('128ms', function() {
    });

    return false;
});

同时不会影响你background-colorouter上课

于 2013-09-07T19:24:41.353 回答
0

我猜你正在寻找nextUntil()

$(this).nextUntil('.outer').slideToggle('218ms');

http://jsfiddle.net/bf7Ke/53/

于 2013-09-07T19:32:55.727 回答