JQuery给loop 元素的button绑定click事件被多次执行

需求

Read More & Read Less 做手风琴功能

问题

Read More Button 的点击一次,全部Loop more 展开
图片描述
图片描述

我尝试过的方法(都不成功)

off('click')
unbind('click')
.one('click')
循环做闭包处理
把onClick 事件单独做成一个function

我希望得到的结果

只对current target 起作用,而不是点击某一个click事件,全部button都响应

以下是我把on click 事件抽离后的代码

HTML

<div class="card">
    <div class="card-block flexLayout">

        <div class="imgContent">
            <img src="$ThemeDir/images/aaron-kitto-hs.png" alt="">
        </div>

        <div class="itemPresenterContent">
            <h2>Aaron</h2>

            <div class="textBox">
                <p>
                        malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
                        malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
            malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
                        malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
                        malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
                        malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultric
                </p>
            </div>

            <button class="read-more">
                Read More
                <i class="fa fa-angle-double-down"></i>
            </button>
            
            <button class="read-less">
                Read Less
                <i class="fa fa-angle-double-up"></i>
            </button>
            <span class="cleanFloat"></span>
        </div>
    </div>
</div>

JS

    var originHeight = $(".read-less, .read-more").parents().find('.textBox').height();
    /* toggle read more or less */
    function toggleMoreOrrLess(btn) {

        $(btn).on('click', function () {
            console.log('test');
            var extendHeight = $(this).parents().find('.textBox > p').height(),
                height = $(this).attr('class').indexOf('read-less') != -1  ? originHeight : extendHeight;

            $(this).parents().find(".textBox").animate({
                "height": height
            });

            $(this).hide();
            $(this).attr('class').indexOf('read-less') != -1 ?  $('.read-more').show() : $('.read-less').show();

            return false;
        })

    };

    for (var i = 0; i< $('.itemPresenter button').length; i++) {
        toggleMoreOrrLess($('.itemPresenter button')[i]);
    }

在function 中设置了一个打印,点击一次,也就是只打印一次。打印$(this)也是当下的元素。
我现在有点晕了。大神们能否提供一个解决方法以及原因?

阅读 4.3k
4 个回答

老生常谈。
要事件代理,不要循环绑定,绑定也不要写在function里。有循环绑定,就可能会出现循环执行,然而这个循环根本没必要。


补充下代码,原有HTML不动,CSS补充(仅为示意,具体样式没抠):

.textBox {
    width: 100%;
    height: 100%;
    overflow: hidden;
    transition: all .6s;
}

.less .textBox {
    height: 30%;
}

.read-less,
.read-more {
    position: relative;
}

.read-less,
.less .read-more {
    display: block;
}

.read-more,
.less .read-less {
    display: none;
}

然后js只需要:

$('.card').on('click', 'button', function(){
    $('.card').toggleClass('less');
});

主要就是在css里用transition控制动画,在父类里直接加减类名控制里边的样式,然后js只要操作(切换)类名就行了。

你的按钮是有两次作用 所以你可以用发父级元素去监听事件的操作 就是addeventlistern

阻止默认,event.preventDefault()

谢谢各位,问题已经解决。bug 来源是 $(target).parents(),这一句将render范围扩大至最外层的包围。所以导致问题出现。我也是疾病乱投医的认为是要loop产生的button导致的问题。后经熊猫桑提醒,最终确定了bug出处。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题