如何使用挖空.js在特定条件下将点击事件绑定到正文

How to bind click event to body under certain conditions using knockout.js?

本文关键字:事件 绑定 正文 条件下 何使用 js      更新时间:2023-09-26

我设计了一个下拉菜单(徒劳地试图跨浏览器一致地设置实际<select>元素的样式),单击该菜单时,会显示一个无序列的下拉列表选项。此功能通过 Knockout 提供.js它使用可观察量来检查下拉列表是应该显示还是隐藏。DOM 结构在这里:

<div id="actionsDropdown">
  <a data-bind="click: toggleDropdownVisibility, css: { active: showDropdown() == true }">Actions</a>
    <ul data-bind="visible: showDropdown">
      <li>Option 1</li>
      <li>Option 2</li>
    </ul>
</div>

这是我的淘汰.js代码:

self.showDropdown = ko.observable(false);
self.toggleDropdownVisibility = function () {
    console.log(self.showDropdown());
    self.showDropdown(!self.showDropdown());
};

这很好用,除了一些事情。

如果下拉列表已经可见,我如何实现逻辑以在单击页面上的其他任何位置时隐藏下拉列表?

我想我可以将点击处理程序绑定到 body 元素,但如果它关闭,它会打开它,这显然不是最佳的。

看到这个jsfiddle:

http://jsfiddle.net/dwp0etrg/9/

我刚刚创建了一个快速自定义绑定处理程序,该处理程序接受 take showDropdown 并将事件侦听器添加到文档中。当 showDropdown 为 true 时,它会绑定侦听器,当 false 时,它会将其删除。

ko.bindingHandlers.dropdown = {
    update: function (element, valueAccessor) {
        var value = valueAccessor();
        var valueUnwrapped = ko.unwrap(value);
        if (valueUnwrapped) {
            $(document).on('click.dropdown', function (e) {
                var $target = $(e.target);
                if ($target.parents('#actionsDropdown').length === 0) {
                    value(false);
                }
            });
        } else {
            $(document).off('click.dropdown');
        }
    }
};

只需更改模板以使用绑定并传递它 showDropdown 可观察。

<div id="actionsDropdown"> 
    <a data-bind="dropdown: showDropdown, 
                  click: toggleDropdownVisibility,
                  css: { active: showDropdown() == true }">Actions</a>
    <ul data-bind="visible: showDropdown">
        <li>Option 1</li>
        <li>Option 2</li>
    </ul>
</div>