如何停止 jQuery slidetoggle 的来回滑动?

3

我对jQuery还不熟悉,但这似乎应该可以正常工作:

$(document).ready(
    function()
    {
        $("#btn_toggle_transcript").click(
            function()
            {
                $("#transcript_container").slideToggle(1000);
            }       
        );
    }
);

...它可以工作,但并不正确。 至少,与预期不同...

我是否正确地假设上面的代码会添加一个单击处理程序到ID为“btn_toggle_transcript”的元素?那么,这个单击处理程序将通过打开目标div(...id为“transcript_container”)来响应单击,如果它关闭了,则关闭它。

当前发生的情况是:点击按钮确实会使div滑动打开。 但是,当它完全打开时,它立即 - 并且没有用户输入 - 再次滑动关闭。

我看到一些论坛帖子建议可能的原因是处理程序被添加两次。 但是,如果我注释掉以上代码,则单击按钮时不执行任何操作。 因此,处理程序没有在其他任何地方添加...

有人能告诉我为什么我的div会自动关闭吗?

按钮的HTML:

<div id="tools_button_container">
    <div class="tools_button" id="btn_toggle_transcript"></div>
</div>
滑动的div的HTML代码(内容是动态设置的):
<div id="transcript_container">
    <div id="transcript_contents"></div>
</div>

同时需要写出CSS样式:

#transcript_container{
z-index:4;
position:absolute;
width:290px;
max-height:455px;
top:51px;
right:-2px;
background-color:#90B2D8;
padding:20px 10px 10px 10px;
border-bottom: 1px solid #000;
border-left: 1px solid #000;
border-right: 1px solid #000;
display:none;
}

#transcript_contents{
max-height:375px;
overflow:auto;
margin:20px 0px 10px 0px;
background-color:#ffffff;
padding:0px 5px 0px 5px;
}

#btn_toggle_transcript {
background: url('images/transcript.png') no-repeat 0 0;
display:block;
}

#circle_btn_toggle_transcript:hover {
background-position: 0px -50px;
}

编辑:

我做了三件事情,似乎有所帮助。为什么它们有效我不知道,但是它们确实有效。

1)Drupal 6.x使用旧版的jQuery(1.2.2)。有一个模块可更新到1.3.2版本。我用1.7.1的文件替换了1.3.2的更新文件,现在我的DOM报告使用jQuery v1.7.1。

2)&3)尽管我只绑定点击事件一次(通过删除绑定并在按钮单击时没有引发任何操作进行验证),但我决定尝试添加一行来删除我的“幻影”绑定,然后再添加实际绑定。基于我的阅读,我决定使用现在推荐的on()和off()方法来添加/删除绑定。我的ready()函数现在如下:

$(document).ready(
function(){
    $("body").off("click", "#btn_toggle_transcript");
    $("body").on("click", "#btn_toggle_transcript",
        function(){
            $("#transcript_container").slideToggle(1000);
        }
    );
}
);

现在,我的滑动div打开并保持打开状态,直到我再次切换关闭。太棒了!非常感谢所有回答/评论的人。您的建议和指导帮助我找到了解决方案。更新:正如我在其中一条评论中提到的那样,这是在Drupal内运行的。同时也提到,如果我注释掉单个绑定,就不会调用任何操作。我的想法是,由于删除了一个绑定就停止调用操作,那么就没有办法绑定两次...愚蠢!虽然我正确地认为只有一块绑定代码,但我完全忘记了我的模块已经将我的js文件添加到页面中。因为我还需要在非Drupal环境中部署我的内容,所以我也手动将js文件添加到我的页面中。...两个包含意味着两个绑定...这是我永远无法挽回的几天!

只需发布的代码,这个工作正常http://jsfiddle.net/FSYEv/,肯定有一些不在这个问题中引起问题的东西。 - undefined
我刚想说,所有这些都是在Drupal内部运行的,所以有可能存在背景中导致问题的某些情况。我真的不知道该去哪里查找或如何找出答案。 - undefined
这可能听起来有点奇怪,但是如果你加入 event.stopPropagation(); 会有什么变化吗? - undefined
我将上面的ready()函数改为:$(document).ready( function() { $("#circle_btn_toggle_transcript").click( function(e) { e.stopPropagation(); $("#circle_transcript_container").slideToggle(1000); } ); } ); ...但是没有任何变化。我做对了吗? - undefined
...还有@James ...谢谢你告诉我jsfiddle.net这个网站。因为我将来可能会做更多的JS开发,这将是一个非常有用的资源。我不知道我所做的设置更改是否反映在结果中,但似乎我正在使用的jQuery版本是1.3.2。至少这是Firebug控制台显示的。我安装了我认为是jQuery 1.7,但我不确定它是否被初始化。或者在这种情况下是否会有所不同。 - undefined
如果可能的话,请尽量使用最新版本的jQuery。您可以在这里找到最新版本:链接 - undefined
3个回答

3

这是一个绑定了两次点击事件的情况。请检查是否发生了这种可能性,例如在js文件中以及html文档内的script标签中。

如果容器是动态的,应该使用live而不是click。

$("selector").live("click", function() { /*body*/ })

你可以试试这个。
$(document).ready(
function(){
    $("body").click( "#btn_toggle_transcript",
        function(){
            if(!$("#transcript_container").hasClass('opened')) {
              $("#transcript_container").slideDown(1000).addClass('opened');
            } else {
              $("#transcript_container").slideUp(1000);
            }
        }
    );
}
);

谢谢你的回答,但是没有帮助。:( - undefined
正如之前提到的,我已尝试移除上面的绑定。通过注释掉这个绑定,按钮不再触发任何操作。因此,我被迫假设这是唯一一个被执行的绑定。如果有第二个绑定被添加在其他地方,我移除这个绑定是否应该仍然调用slideToggle()呢?另外,我阅读了live()方法的相关文档。它从1.7版本开始已被弃用,现在推荐使用on()方法来附加事件处理程序。http://api.jquery.com/live/ - undefined
谢谢,Pankaj。虽然你的回答没有直接帮到我,但它给了我那个确实起作用的一点信息。点赞!:) - undefined

2

我的答案末尾有一个新的解决方案。

我已经遇到过这个问题很多次,但只调用了一次该函数。
由于某种原因,在每个小步骤中,tween.end变量都会恢复为0。我的解决方法如下:

$('body').on('click', '.toggle', function() {
    var ul = $(this).next('ul');
    if (!$(ul).hasClass('open')) {
        $(ul).slideDown({
            step: function(now, tween) {
                if (tween.end == 0) {
                    stop();
                }
            },
            complete: function() {
                $(ul).addClass('open');
            }
        });
    } else {
        $(ul).slideUp('', '', function() {
            $(ul).removeClass('open');
        });
    }
});

有点混乱,但这是我能想到的所有内容,因为我找不到另一个调用该函数的方法。

编辑

一个旧问题-有了新解决方案。
只需在slideToggle之前添加stop()即可修复不断重复的yo-yo效果。

$('#element').stop().slideToggle();


$('#element').stop().slideToggle(); 运行成功 - undefined

0
你等待事件结束后再添加类。
$(document).ready(
    function(){
        $("body").click( "#btn_toggle_transcript",
            function(){
                if(!$("#transcript_container").hasClass('opened')) {
                    $("#transcript_container").slideDown(1000,function(){$(this).addClass('opened')});
                } else {
                    $("#transcript_container").slideUp(1000,function(){$(this).removeClass('opened')});
                }
            }
        );
    }
);

SO是一个仅限英文的网站。请将您的答案翻译成中文。 - undefined
就像Zippy说的那样。现在,我已经标记了回答中的“建议删除”选项。如果你翻译第一行的话,这个回答可能会很好。 - undefined

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