在knockout.js

时间:2016-07-26 16:33:41

标签: javascript jquery knockout.js

我在淘汰赛中的一个事件后添加了一个类,我似乎无法弄清楚如何在点击页面的其余部分时让div离开div。这是我的代码。我尝试了一些事无济于事。当你点击页面上的任何其他地方时,我想删除.nav-menu.cart上的“open”类。感谢

self.addProductToCart = function(data) {
 var $productNotification = $(".product-notification");
 ax.Cart.addCartItem({product_id:data.id, name:data.name, description:data.description});
 $productNotification.slideDown(1000).fadeOut(200);
 $(".nav-menu.cart").addClass("open");

};

1 个答案:

答案 0 :(得分:1)

每当您需要更改DOM时,您应该尝试通过knockout data-bind来实现。其中大部分都可以通过淘汰赛的默认绑定来完成;一些东西需要自定义绑定。

对于第一部分:添加 open 类应该通过css bind发生:

data-bind="css: { 'classname' : state }"

在您的viewmodel中,添加cartIsOpen可观察对象和openCart方法。

self.isOpen = ko.observable(false);

现在,您可以通过将此数据绑定添加到其容器元素来直观地打开购物车:

data-bind="css: {'open': isOpen }"

jquery行可以替换为:

self.isOpen(true);

和淘汰将照顾css。

现在,对于(更复杂的)第二部分:

听取容器外的事件不是淘汰赛的常规clickevent绑定所能做到的。因此,您必须编写自定义绑定。

在外面某个元素可能会非常棘手;我建议搜索堆栈溢出以获得一些一般性建议。你必须非常小心event.stopPropagation()才能发挥作用。

在下面的示例中,我编写了一个clickOutside绑定的粗略示例。请注意,它不是"已完成"例如:

  • 页面中的任何点击都会触发closeOnClickOutside方法;当isOpen设置为true时,您需要找到附加监听器的方法,并且一旦将其设置为处理 false
  • 每当您想要打开菜单时,您都需要明确停止点击事件到达文档。 (示例中为cancelBubble)。否则,菜单会立即打开和关闭。



var elementContainsChild = function(parent, child) {
  // http://stackoverflow.com/a/2234986/3297291
  var node = child.parentNode;
  while (node !== null) {
    if (node === parent) {
      return true;
    }
    node = node.parentNode;
  }
  return false;
};

ko.bindingHandlers.clickOutside = {
  init: function(element, valueAccessor) {
    var cb = valueAccessor();
    var closeOnClickOutside = function(e) {
      if (e.target !== element && 
          !elementContainsChild(element, e.target)) {
          cb();
      }
    };
    
    document.addEventListener("click", closeOnClickOutside);
  }
}

var vm = {
  isOpen: ko.observable(false)
};

ko.applyBindings(vm);

html, body { height: 100%; background: grey; }
.menu { background: yellow; display: none; }
.menu.open { display: block; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<button data-bind="click: isOpen.bind(null, true), clickBubble: false">open menu</button>
<div class="menu" data-bind="css: {'open' : isOpen }, clickOutside: isOpen.bind(null, false)">
  <ul>
    <li>Menu item</li>
    <li>Menu item</li>
    <li>Menu item</li>
    <li>Menu item</li>
  </ul>
</div>
&#13;
&#13;
&#13;