2016-07-26 66 views
0

我在淘汰赛中添加了一个类,并且我似乎无法弄清楚如何将该类关闭点击页面的其余部分。这是我的代码。我尝试了几件事情,但无济于事。当您点击页面上的任何其他位置时,我想要移除.nav-menu.cart上的“打开”类。谢谢尝试在单击其他任何位置后在下拉菜单中删除类,然后单击其中的其他任何位置,然后点击knockout.js

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

无论何时您需要更改DOM,您都应该尝试通过敲除数据绑定来完成此操作。大部分可以通过敲除的默认绑定来完成;有些东西需要自定义绑定。

对于第一部分:添加开放类应通过css绑定发生:

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

在您的视图模型,添加一个cartIsOpen观察到的和openCart方法。

self.isOpen(true); 

和淘汰赛:

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

jQuery的线可以被替换为:现在

self.isOpen = ko.observable(false); 

,您可以通过添加这个数据绑定到其容器元素在视觉上打开你的车会照顾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>

+0

我意识到,哇。我开始讨论这种错误。我会尝试你所说的。非常有帮助 – erics15

+0

还有一个问题 - 我将如何链接到已经看起来像这样的按钮。 ?谢谢! – erics15

+1

如果'addProductToCart'应该打开菜单('self.isOpen(true)'),则还需要将'clickBubble:false'数据绑定添加到按钮。如果你不这样做,按钮上的点击事件将(1)打开菜单,(2)一直向上冒泡,记录它(3)再次关闭菜单的位置(假设你还没有改变自定义绑定)。 – user3297291

相关问题