为什么 jQuery 不切换这个 div?

发布于 2024-10-07 01:18:51 字数 4012 浏览 0 评论 0原文

我有一组代表故事类别的 div。在每个类别中,都有一个 div 保存类别标题,还有一个兄弟 div 包含故事摘要。

我一开始隐藏了所有故事 div,除了包含默认故事的类别;它的故事 div 开始可见(下面的 cat2):

[ cat1   < ]
[ cat2   V ]
  - story2-1
  - story2-2
[ cat3   < ]

当我单击任何其他类别头时,我删除了在所有类别头 div 上设置下三角图标的“扩展”类,隐藏所有故事 div,然后在单击的类别头上切换“扩展”类,最后切换与单击的类别头同级的故事 div。

如果我单击除当前展开的类别头之外的类别头,所有这些都可以正常工作。

问题:如果我单击当前展开的类别头将其折叠,那么它们全部都折叠起来,什么也不会发生。或者更具体地说,当我记录结果时,我看到故事 div 将其“显示”属性设置为“阻止”,然后立即再次设置为“无”。为什么???

代码

<html>
<head>
<style type="text/css">
    .category        { width: 200px; }
    .category-hed    { cursor: pointer; }
    .category-hed h2 {
        background-image: url( /_img/b/category-hed-arrow-collapsed.gif );
        background-repeat: no-repeat;
        background-position: center right;
    }
    .category-hed h2.expanded    {
        background-image: url( /_img/b/category-hed-arrow-expanded.gif );
    }
    .category .stories  {   /* default hidden; clicking category-hed will toggle it */
        display: none;
    }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        // set click handlers on the category section headers to expand/collapse the sections
        $(".category-hed").click( function() {
            $(".category-hed h2").removeClass("expanded");      // unset the 'expanded' indicators in all categories
            $(".stories").hide();                               // hide the "stories" divs in all categories

            // TODO: this doesn't collapse an already-expanded section... why?
            $("h2", this).toggleClass("expanded");  // 2nd arg to $() sets context of the selection: h2 under this
            $(this).siblings(".stories").toggle();  // show this category's "stories" div
        });
        // the default story's category section should initially be expanded
        var defaultStoryCatID = "#category-2";
        $( "h2", defaultStoryCatID ).toggleClass("expanded");
        $( ".stories", defaultStoryCatID ).show();
    });
</script>

</head>
<body>
    <div class="category" id="category-1">
        <!-- nested H2 below to aid border styling; CSS omitted -->
        <div class="category-hed"><h2>Category 1</h2></div>
        <div class="stories">
            <div class="story">
                <h3>cat 1 story1 head</h3>
                <p>... the story...</p>
            </div>
            <div class="story">
                <h3>cat 1 story2 head</h3>
                <p>... another story...</p>
            </div>
        </div>
    </div>
    <div class="category" id="category-2">
        <div class="category-hed"><h2>Category 2</h2></div>
        <div class="stories">
            <div class="story">
                <h3>cat 2 story1 head</h3>
                <p>... the story...</p>
            </div>
            <div class="story">
                <h3>cat 2 story2 head</h3>
                <p>... another story...</p>
            </div>
        </div>
    </div>
    <div class="category" id="category-3">
        <div class="category-hed"><h2>Category 3</h2></div>
        <div class="stories">
            <div class="story">
                <h3>cat 3 story1 head</h3>
                <p>... the story...</p>
            </div>
            <div class="story">
                <h3>cat 3 story2 head</h3>
                <p>... another story...</p>
            </div>
        </div>
    </div>
</body>
</html>

I have a set of divs that represent story categories. In each category, there's a div holding the category head, and a sibling div containing summaries of the stories.

I start out with all the stories divs hidden, except for the category that contains the default story; its stories div starts out visible (cat2 below):

[ cat1   < ]
[ cat2   V ]
  - story2-1
  - story2-2
[ cat3   < ]

When I click on any of the other category heads, I remove the 'expanded' class that sets the down-triangle icon on all the category head divs, hide all the story divs, then toggle the 'expanded' class on the clicked category head, and finally toggle the stories div that's the sibling of the clicked category head.

All this work fine if I click a category head other than the currently expanded one.

PROBLEM: If I click the currently-expanded category head to collapse it, so they're ALL collapsed, nothing happens. Or more specifically, when I log the results, I see that the story div gets its 'display' property set to 'block' and then immediately to 'none' again. Why???

The code

<html>
<head>
<style type="text/css">
    .category        { width: 200px; }
    .category-hed    { cursor: pointer; }
    .category-hed h2 {
        background-image: url( /_img/b/category-hed-arrow-collapsed.gif );
        background-repeat: no-repeat;
        background-position: center right;
    }
    .category-hed h2.expanded    {
        background-image: url( /_img/b/category-hed-arrow-expanded.gif );
    }
    .category .stories  {   /* default hidden; clicking category-hed will toggle it */
        display: none;
    }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        // set click handlers on the category section headers to expand/collapse the sections
        $(".category-hed").click( function() {
            $(".category-hed h2").removeClass("expanded");      // unset the 'expanded' indicators in all categories
            $(".stories").hide();                               // hide the "stories" divs in all categories

            // TODO: this doesn't collapse an already-expanded section... why?
            $("h2", this).toggleClass("expanded");  // 2nd arg to $() sets context of the selection: h2 under this
            $(this).siblings(".stories").toggle();  // show this category's "stories" div
        });
        // the default story's category section should initially be expanded
        var defaultStoryCatID = "#category-2";
        $( "h2", defaultStoryCatID ).toggleClass("expanded");
        $( ".stories", defaultStoryCatID ).show();
    });
</script>

</head>
<body>
    <div class="category" id="category-1">
        <!-- nested H2 below to aid border styling; CSS omitted -->
        <div class="category-hed"><h2>Category 1</h2></div>
        <div class="stories">
            <div class="story">
                <h3>cat 1 story1 head</h3>
                <p>... the story...</p>
            </div>
            <div class="story">
                <h3>cat 1 story2 head</h3>
                <p>... another story...</p>
            </div>
        </div>
    </div>
    <div class="category" id="category-2">
        <div class="category-hed"><h2>Category 2</h2></div>
        <div class="stories">
            <div class="story">
                <h3>cat 2 story1 head</h3>
                <p>... the story...</p>
            </div>
            <div class="story">
                <h3>cat 2 story2 head</h3>
                <p>... another story...</p>
            </div>
        </div>
    </div>
    <div class="category" id="category-3">
        <div class="category-hed"><h2>Category 3</h2></div>
        <div class="stories">
            <div class="story">
                <h3>cat 3 story1 head</h3>
                <p>... the story...</p>
            </div>
            <div class="story">
                <h3>cat 3 story2 head</h3>
                <p>... another story...</p>
            </div>
        </div>
    </div>
</body>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空名 2024-10-14 01:18:51

首先,您的代码格式错误。例如,

<div class="category" id="category-3">
    <div class="category-hed"><h2>Category 3</h2></div>
        <div class="stories">
            <div class="story">
                <h3>cat 3 story1 head</h3>
                <p>... the story...</p>
            </div>
            <div class="story">
                <h3>cat 3 story2 head</h3>
                <p>... another story...</p>
            </div>
        </div>
    </div>
</div>

其中有太多 /div 标签。它应该看起来像这样...

<div class="category" id="category-3">
    <div class="category-hed"><h2>Category 3</h2></div>
    <div class="stories">
        <div class="story">
            <h3>cat 3 story1 head</h3>
            <p>... the story...</p>
        </div>
        <div class="story">
            <h3>cat 3 story2 head</h3>
            <p>... another story...</p>
         </div>
    </div>
</div>

我在点击功能中做了一些重新排序...

    $(".category-hed").click( function() {
        // TODO: this doesn't collapse an already-expanded section... why?
        $("h2", this).toggleClass("expanded");  // 2nd arg to $() sets context of the selection: h2 under this
        $(this).siblings(".stories").toggle();  // show this category's "stories" div

        $(".category-hed").not(this).find("h2").removeClass("expanded");      // unset the 'expanded' indicators in all categories
        $(".category-hed").not(this).siblings(".stories").hide();             // hide the "stories" divs in all categories
    });

尝试一下,让我知道它是如何进行的!

The first thing is that your code is malformed. For example,

<div class="category" id="category-3">
    <div class="category-hed"><h2>Category 3</h2></div>
        <div class="stories">
            <div class="story">
                <h3>cat 3 story1 head</h3>
                <p>... the story...</p>
            </div>
            <div class="story">
                <h3>cat 3 story2 head</h3>
                <p>... another story...</p>
            </div>
        </div>
    </div>
</div>

has one too many /div tags in it. It should look like this...

<div class="category" id="category-3">
    <div class="category-hed"><h2>Category 3</h2></div>
    <div class="stories">
        <div class="story">
            <h3>cat 3 story1 head</h3>
            <p>... the story...</p>
        </div>
        <div class="story">
            <h3>cat 3 story2 head</h3>
            <p>... another story...</p>
         </div>
    </div>
</div>

I did a little bit of reordering in the click function...

    $(".category-hed").click( function() {
        // TODO: this doesn't collapse an already-expanded section... why?
        $("h2", this).toggleClass("expanded");  // 2nd arg to $() sets context of the selection: h2 under this
        $(this).siblings(".stories").toggle();  // show this category's "stories" div

        $(".category-hed").not(this).find("h2").removeClass("expanded");      // unset the 'expanded' indicators in all categories
        $(".category-hed").not(this).siblings(".stories").hide();             // hide the "stories" divs in all categories
    });

Try that out and let me know how it goes!

月亮坠入山谷 2024-10-14 01:18:51

如果我正确理解你的问题,那是因为当你点击已经展开的category-hed时,它首先“折叠”(通过删除expanded类),然后扩展的类会立即由.toggleClass()重新添加。在你的代码中,总会有一些东西最终会被扩展,因为之前的状态没有被考虑在内。像这样简单的事情应该可以解决问题:

$(".category-hed").click( function() {
            if($(this).hasClass("expanded")
               var dont_reexpand = true;
            $(".category-hed h2").removeClass("expanded");      // unset the 'expanded' indicators in all categories
            $(".stories").hide();                               // hide the "stories" divs in all categories
            if(!dont_reexpand) {
                // TODO: this doesn't collapse an already-expanded section... why?
                $("h2", this).toggleClass("expanded");  // 2nd arg to $() sets context of the selection: h2 under this
                $(this).siblings(".stories").toggle();  // show this category's "stories" div
            }
        });

可能有更好的方法来做到这一点,但你明白了。

If I undersand your question correctly, it's because when you click on the already-expanded category-hed, it is first "collapsed" (by removing the expanded class), then the expanded class is immediately re-added by .toggleClass(). In your code, there is always going to be something that ends up being expanded, because prior state is not accounted for. Something as simple as this should fix the problem:

$(".category-hed").click( function() {
            if($(this).hasClass("expanded")
               var dont_reexpand = true;
            $(".category-hed h2").removeClass("expanded");      // unset the 'expanded' indicators in all categories
            $(".stories").hide();                               // hide the "stories" divs in all categories
            if(!dont_reexpand) {
                // TODO: this doesn't collapse an already-expanded section... why?
                $("h2", this).toggleClass("expanded");  // 2nd arg to $() sets context of the selection: h2 under this
                $(this).siblings(".stories").toggle();  // show this category's "stories" div
            }
        });

There are probably better ways to do this, but you get the idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文