Knockout.JS - 在div外部单击时运行函数

时间:2017-03-03 03:17:20

标签: javascript html knockout.js

我正在尝试使用knockout在div外部单击时执行一个函数。我试图通过使用带有模糊的事件绑定来实现。我想我很亲近,我只需要一些帮助。

filterFromList函数工作正常。

相关JS

self.filterFromList = function (item) {
    self.selectedName(item.name);
    self.location().forEach(function(place) {
        if (place.name === self.selectedName()) {
            place.showLocation(true);
            place.marker.setVisible(true);
        } else {
            place.showLocation(false);
            place.marker.setVisible(false);
        }
    });
};

self.unfilter = function (item) {
    console.log("blurring");
    self.location().forEach(function (place) {
        place.showLocation(true);
        place.marker.setVisible(true);
    })
};

相关HTML

<ul data-bind="foreach: location">
<a class="location-click" data-bind="click: $parent.filterFromList, event: { blur: $parent.unfilter }">
    <li class="location-block" data-bind="visible: showLocation">
        <img class="location-img" data-bind="attr: {src: imgURL}" />
        <h4 data-bind="text: name"></h4>
        <hr>
    </li>
</a>
</ul>

3 个答案:

答案 0 :(得分:0)

您可以使用自定义bindingHandler(fiddle)执行此操作:

ko.bindingHandlers.clickOutside = {
  init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    var fn = ko.utils.unwrapObservable(valueAccessor());

    $('html').on('click', function(e) {
      if (!($.contains(element, e.target) || element === e.target)) {
        fn();
      }
    });
  },
}

var vm = {
  clickOutside: function(msg) {
    console.log(msg);
  }
};

ko.applyBindings(vm);

HTML:

<div style="background-color:green;">
  Outside area
  <div data-bind="clickOutside: clickOutside.bind($data, 'clicked outside of red div')" style="background-color:red;">
  inside area
  <ul>
    <li><a href="#">Link 1</a></li>
    <li><a href="#">Link 2</a></li>
    <li><a href="#">Link 3</a></li>
  </ul>
</div>

基本上,我们的想法是将事件监听器添加到可能的最外层元素(<html>),并检查点击目标是直接还是间接在($.contains(what contains, what is contained))所需容器内。如果是,则不执行任何操作,如果没有,则调用绑定函数。

答案 1 :(得分:0)

通过向相关div添加tabindex属性来解决此问题。谢谢你的帮助!

<a class="location-click" tabindex="0" data-bind="click: $parent.filterFromList, event: { blur: $parent.unfilter } ">
            <li class="location-block" data-bind="visible: showLocation">
                <img class="location-img" data-bind="attr: {src: imgURL}"></img>
                <h4 data-bind="text: name"></h4>
                <hr>
            </li>
</a>

答案 2 :(得分:0)

注意不能与敲除绑定(如和一起使用)配合 第一次显示元素容器初始化很好,如果再次隐藏并显示,请单击外部不再起作用

,而不是使用:

 ko.bindingHandlers.clickOutside = {
        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var fn = ko.utils.unwrapObservable(valueAccessor().fn);
            var uid = ko.utils.unwrapObservable(valueAccessor().uid);
            $('html').on('click', function (e) {
                if ($(e.target).parents('.' + uid).length === 0) {
                    fn();
                }
            });
        },
    }

将一个UID分配给父对象,然后使用“ with”和“ if”绑定