简体   繁体   English

Javascript 事件计时 + 3rd 方事件,寻找比 setTimeOut() 更好的替代方案

[英]Javascript event timing + 3rd party events, looking for a better alternative than setTimeOut()

I have the following HTML element stack:我有以下 HTML 元素堆栈:

<div class="btn-group btnSortAssType" data-toggle="buttons">
    <label class="btn ink-reaction btn-primary active">
        <input type="checkbox" value="m">Model
    </label>
    <label class="btn ink-reaction btn-primary active">
        <input type="checkbox" value="n">Assignment
    </label>
    <label class="btn ink-reaction btn-primary active">
        <input type="checkbox" value="p">Multi
    </label>
</div>

Since the button build above is not mutually exclusive, I am going over array + show/hide elements.由于上面的按钮构建不是相互排斥的,我将介绍数组 + 显示/隐藏元素。

 $('.btnSortAssType').on('click', function (event) {
        let $allLables;
        var assTypeToShow = [];
        $(`.top-row`).hide();
        setTimeout(function () {
            $allLables = $('.btnSortAssType label.active');
            $allLables.each((index, label) =>{
                $(`.top-row[assignment_type="${$(label).find('input').val()}"]`).show();

            });
        })
    });

If you read the js abpve, you will see the element check going through setTimeout() , reason being: without it, it will miss the last click (so if 2 out of 3 are active, and clicking on the the last un-active element will still show 2 active).如果您阅读 js abpve,您将看到元素检查通过setTimeout() ,原因是:没有它,它将错过最后一次点击(因此,如果 3 个中有 2 个处于活动状态,并单击最后一个未活动的元素仍将显示 2 活动)。

I reckon this happens due to event timing between my code and bootstrap.js, where the method setting the element active somehow comes after my code, in my mind I assumed the event-loop didn't have that bootstrap active change in the event stack, so I used setTimeout() , I believe waits for the previous event stack to finish and runs after (null delay).我认为这是由于我的代码和 bootstrap.js 之间的事件计时造成的,其中将元素设置为 active 的方法以某种方式出现我的代码之后,在我看来,我认为事件循环在事件堆栈中没有引导程序主动更改,所以我使用了setTimeout() ,我相信等待前一个事件堆栈完成并在(空延迟)之后运行。

The results of having the above setTimeout() is 100% seamless, yet I want to know what I've missed here 'cause using setTimeout() seems like a cheap hack and I was wondering what you guys have in mind.使用上述setTimeout()是 100% 无缝的,但我想知道我在这里错过了什么,因为使用setTimeout()似乎是一个廉价的黑客,我想知道你们在想什么。

Many thanks for sharing, Bud.非常感谢分享,巴德。

The Bootstrap handler is attached to the document, and runs in the bubbling phase. Bootstrap 处理程序附加到文档,并在冒泡阶段运行。 So, event listeners attached to descendants of the document which also run in the bubbling phase will run before the Bootstrap handlers:因此,附加到也在冒泡阶段运行的文档后代的事件侦听器将Bootstrap 处理程序之前运行:

 $('.btnSortAssType').on('click', function(event) { console.log($('.active').length); });
 .active { color: blue; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.js"></script> <div class="btn-group btnSortAssType" data-toggle="buttons"> <label class="btn ink-reaction btn-primary active"> <input type="checkbox" value="m" checked>Model </label> <label class="btn ink-reaction btn-primary active"> <input type="checkbox" value="n" checked>Assignment </label> <label class="btn ink-reaction btn-primary active"> <input type="checkbox" value="p" checked>Multi </label> </div>

You can fix it by attaching your event handler to the document as well, and running your script after Bootstrap's (since listeners attached to the same element will run in the order they're attached):您也可以通过将事件处理程序附加到文档在 Bootstrap 之后运行脚本来修复它(因为附加到同一元素的侦听器将按照它们附加的顺序运行):

 $(document).on('click', '.btnSortAssType', function(event) { console.log($('.active').length); });
 .active { color: blue; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.js"></script> <div class="btn-group btnSortAssType" data-toggle="buttons"> <label class="btn ink-reaction btn-primary active"> <input type="checkbox" value="m" checked>Model </label> <label class="btn ink-reaction btn-primary active"> <input type="checkbox" value="n" checked>Assignment </label> <label class="btn ink-reaction btn-primary active"> <input type="checkbox" value="p" checked>Multi </label> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM