如何使用 Knockout.js 在鼠标悬停时更改 CSS 类



我有一个由 Knockout.js foreach 数据绑定填充的图像网格。默认情况下,网格中的每个图像都有一个由背景颜色设置的黑色轮廓。当用户将鼠标悬停在每个图像上时,我希望该轮廓变为白色以表示它已被突出显示。

目前,我正在使用两个事件处理程序,一个用于mouseenter,一个用于mouseleave
第一个将图像的 CSS 类更改为具有白色背景的类。后者将其改回黑色。但是,当鼠标进入图像时,两者都会被调用(通过调试确认),因此看不到任何更改。

该网页如下所示:(注意:每个图像都有一个表示图像文件位置的fileName属性。有两个CSS类称为blackwhite,每个高亮状态对应一个。

<div id="palette-container" data-bind="foreach: images" style="display: inline-block">
    <div style="float: left">
        <img class="black" data-bind="attr: { id: fileName, src: $parent.imagePath(fileName) }, 
                                      event: { mouseenter: $parent.toWhite(fileName), mouseleave: $parent.toBlack(fileName) }, 
                                      style: { width: $parent.size, height: $parent.size }">
    </div>
</div>

正如你所看到的,我现在没有以一种非常优雅的方式做到这一点。我将每个元素的id绑定到其唯一的文件名属性。然后,我将 fileName 传递到事件处理程序中,以便可以通过 id 访问该元素以更改 CSS 类。

(A) 为什么鼠标进入图像时同时调用mouseentermouseleave

(B) 实现所需突出显示功能的更简单方法是什么?

Knockout 的目的是通过绑定处理程序以声明方式将视图(您的 HTML)连接到您的视图模型(JavaScript 对象)。但是,并非每个可能的 DOM 到视图模型交互都具有预定义的绑定处理程序。

在您的特定情况下(更改样式),您可以简单地使用 :hover CSS 伪类。您的视图会响应鼠标移动,但您的视图模型不会注意到任何这些。

如果要更改不同的 DOM 属性以响应鼠标移动,例如元素的文本,CSS 将不再起作用。您可以"手动"使用 KNOCKOUT 的event绑定 - 也可以创建自定义绑定处理程序,用于设置视图模型的属性之一以响应 mouseentermouseleave 事件。

自定义绑定处理程序的优点是,您现在有一个可以基于其他行为的实际可观察量,并且您在视图中要执行的键入更少,这在多次使用它时非常有用。

悬停时,以下内容会更改元素的文本和 CSS 类:

ko.bindingHandlers.hover = {
    init: function (element, valueAccessor) {
        var value = valueAccessor();
        ko.applyBindingsToNode(element, {
            event: {
                mouseenter: function () { value(true) },
                mouseleave: function () { value(false) }
            }
        });
    }
}
function Item() {
  this.isHovering = ko.observable(false);
}
ko.applyBindings({
  items: [
    new Item(),
    new Item(),
    new Item(),
    new Item(),
    new Item()
  ]
});
div.item {
  float: left;
  width: 50px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  border: 1px solid black;
  margin: 0 5px 5px 0;
}
div.item.active {
  border-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="foreach: items">
  <div class="item" data-bind="
    hover: isHovering, text: isHovering, css: {active: isHovering}
  ">
  </div>
</div>

为什么不保持简单。使用 CSS :hover

//add a hover effect to class .black
.black{ 
border: solid 5px black
} .black:hover { 
border: solid 5px green;
} 

JSFIDDLE: http://jsfiddle.net/nmx2og9g/1/

最新更新