鍍金池/ 問(wèn)答/網(wǎng)絡(luò)安全  HTML/ JQuery給loop 元素的button綁定click事件被多次執(zhí)行

JQuery給loop 元素的button綁定click事件被多次執(zhí)行

需求

Read More & Read Less 做手風(fēng)琴功能

問(wèn)題

Read More Button 的點(diǎn)擊一次,全部Loop more 展開(kāi)
圖片描述
圖片描述

我嘗試過(guò)的方法(都不成功)

off('click')
unbind('click')
.one('click')
循環(huán)做閉包處理
把onClick 事件單獨(dú)做成一個(gè)function

我希望得到的結(jié)果

只對(duì)current target 起作用,而不是點(diǎn)擊某一個(gè)click事件,全部button都響應(yīng)

以下是我把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 中設(shè)置了一個(gè)打印,點(diǎn)擊一次,也就是只打印一次。打印$(this)也是當(dāng)下的元素。
我現(xiàn)在有點(diǎn)暈了。大神們能否提供一個(gè)解決方法以及原因?

回答
編輯回答
傲寒

你的按鈕是有兩次作用 所以你可以用發(fā)父級(jí)元素去監(jiān)聽(tīng)事件的操作 就是addeventlistern

2017年3月10日 14:33
編輯回答
別逞強(qiáng)

老生常談。
要事件代理,不要循環(huán)綁定,綁定也不要寫在function里。有循環(huán)綁定,就可能會(huì)出現(xiàn)循環(huán)執(zhí)行,然而這個(gè)循環(huán)根本沒(méi)必要。


補(bǔ)充下代碼,原有HTML不動(dòng),CSS補(bǔ)充(僅為示意,具體樣式?jīng)]摳):

.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控制動(dòng)畫,在父類里直接加減類名控制里邊的樣式,然后js只要操作(切換)類名就行了。

2018年3月23日 02:07
編輯回答
蔚藍(lán)色

謝謝各位,問(wèn)題已經(jīng)解決。bug 來(lái)源是 $(target).parents(),這一句將render范圍擴(kuò)大至最外層的包圍。所以導(dǎo)致問(wèn)題出現(xiàn)。我也是疾病亂投醫(yī)的認(rèn)為是要loop產(chǎn)生的button導(dǎo)致的問(wèn)題。后經(jīng)熊貓桑提醒,最終確定了bug出處。

2018年5月6日 06:52
編輯回答
使勁操

阻止默認(rèn),event.preventDefault()

2017年10月15日 23:29