我设计了一个下拉菜单(试图在浏览器中一致地设置实际<select>
元素的样式)是徒劳的,点击后会显示一个无序的下拉选项列表。此功能由Knockout.js提供,它使用observable来检查是否应显示或隐藏下拉列表。 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>
这是我的Knockout.js代码:
self.showDropdown = ko.observable(false);
self.toggleDropdownVisibility = function () {
console.log(self.showDropdown());
self.showDropdown(!self.showDropdown());
};
除了一些事情之外,这很有效。
如果下拉菜单已经显示,如何点击页面上的其他位置时,如何实施逻辑以隐藏下拉列表?
我猜测我可以将点击处理程序绑定到body
元素,但如果它被关闭则打开它,这显然不是最佳的。
答案 0 :(得分:1)
见这个jsfiddle:
http://jsfiddle.net/dwp0etrg/9/
我刚刚创建了一个快速的自定义绑定处理程序,它接受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 observable。
<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>