Turbolinks 5,jQuery 3:无论如何要避免 event.off(...).on(...) 重复事件?
Turbolinks 5, jQuery 3: anyway to avoid event.off(...).on(...) for duplicate events?
我正在使用 Turbolinks 5 和 jQuery 3 构建一个 Rails 4 应用程序。
在我加载应用程序的主要 global.coffee
上,我使用 CoffeeScript class 来抽象一些事件处理:
# app/javascripts/global.coffee
$(document).on "turbolinks:load", ->
App.MD.ExpansionPanel.init()
# app/javascripts/expansion_panel.coffee
class App.MD.ExpansionPanel
@init: () ->
$(document).off("click", "[data-behavior='expansion-panel-toggle']").on "click", "[data-behavior='expansion-panel-toggle']", (e) ->
$panel = $(this).closest("[data-behavior='expansion-panel']")
$details = $panel.find("[data-behavior='expansion-panel-details']")
if $panel.attr("data-state") == "expanded"
$panel.attr("data-state", "collapsed")
else
$panel.attr("data-state", "expanded")
# Some sample HTML (clicking any toggle element toggles between the summary or detail view)
<div data-behavior="expansion-panel">
<div data-behavior="expansion-panel-summary">
<div data-behavior="expansion-panel-toggle">Summary Toggle</div>
</div>
<div data-behavior="expansion-panel-details">
<div data-behavior="expansion-panel-toggle">Details Toggle</div>
</div>
</div>
问题是,事件触发了多次,而我的 expand/collapse 面板会切换这两个事件,从而使面板返回到原始状态。
我通过使用 .off("click", ...).on("click", ...)
先删除 click
事件然后重新添加它来解决这个问题,但有些事情告诉我这不是一个很好的解决方案,因为我'以前从来没有这样做过。
是否有更高效的方法来设置此事件处理程序?
我通过 AJAX 添加了动态内容,这就是我将事件添加到 document
本身而不是某些父上下文的原因。
似乎 $(document).on('click','.selector', function(){...})
应该声明在 $(document).on('turbolinks:load', function(event) {..});
的 之外 。
这引导我找到解决方案:https://www.rubydoc.info/gems/jquery-turbolinks/2.1.0#Events_firing_twice_or_more
当前的文档说了类似的话:
When possible, avoid using the turbolinks:load event to add other
event listeners directly to elements on the page body. Instead,
consider using event delegation to register event listeners once on
document or window.
-- https://github.com/turbolinks/turbolinks#observing-navigation-events
我有一个类似的案例(一个关闭-canvas 菜单),它只适用于首先取消绑定 (*.off()
) 事件。现在在 turbolinks:load
之外绑定事件,它按预期工作。
我正在使用 Turbolinks 5 和 jQuery 3 构建一个 Rails 4 应用程序。
在我加载应用程序的主要 global.coffee
上,我使用 CoffeeScript class 来抽象一些事件处理:
# app/javascripts/global.coffee
$(document).on "turbolinks:load", ->
App.MD.ExpansionPanel.init()
# app/javascripts/expansion_panel.coffee
class App.MD.ExpansionPanel
@init: () ->
$(document).off("click", "[data-behavior='expansion-panel-toggle']").on "click", "[data-behavior='expansion-panel-toggle']", (e) ->
$panel = $(this).closest("[data-behavior='expansion-panel']")
$details = $panel.find("[data-behavior='expansion-panel-details']")
if $panel.attr("data-state") == "expanded"
$panel.attr("data-state", "collapsed")
else
$panel.attr("data-state", "expanded")
# Some sample HTML (clicking any toggle element toggles between the summary or detail view)
<div data-behavior="expansion-panel">
<div data-behavior="expansion-panel-summary">
<div data-behavior="expansion-panel-toggle">Summary Toggle</div>
</div>
<div data-behavior="expansion-panel-details">
<div data-behavior="expansion-panel-toggle">Details Toggle</div>
</div>
</div>
问题是,事件触发了多次,而我的 expand/collapse 面板会切换这两个事件,从而使面板返回到原始状态。
我通过使用 .off("click", ...).on("click", ...)
先删除 click
事件然后重新添加它来解决这个问题,但有些事情告诉我这不是一个很好的解决方案,因为我'以前从来没有这样做过。
是否有更高效的方法来设置此事件处理程序?
我通过 AJAX 添加了动态内容,这就是我将事件添加到 document
本身而不是某些父上下文的原因。
似乎 $(document).on('click','.selector', function(){...})
应该声明在 $(document).on('turbolinks:load', function(event) {..});
的 之外 。
这引导我找到解决方案:https://www.rubydoc.info/gems/jquery-turbolinks/2.1.0#Events_firing_twice_or_more
当前的文档说了类似的话:
When possible, avoid using the turbolinks:load event to add other event listeners directly to elements on the page body. Instead, consider using event delegation to register event listeners once on document or window. -- https://github.com/turbolinks/turbolinks#observing-navigation-events
我有一个类似的案例(一个关闭-canvas 菜单),它只适用于首先取消绑定 (*.off()
) 事件。现在在 turbolinks:load
之外绑定事件,它按预期工作。