【问题标题】:How to use Knockout.js to change a CSS class on mouseover?如何使用 Knockout.js 在鼠标悬停时更改 CSS 类?
【发布时间】:2015-03-31 11:50:53
【问题描述】:

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

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

HTML 如下: (注意:每个图像都有一个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 属性。然后我将 fileName 传递给事件处理程序,以便可以通过 id 访问元素以更改 CSS 类。

(A) 为什么鼠标进入图片时mouseentermouseleave都被调用了?

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

【问题讨论】:

标签: javascript css html knockout.js


【解决方案1】:

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

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

如果您想更改不同的 DOM 属性以响应鼠标移动,例如元素的文本,CSS 将不再起作用。您可以“手动”使用淘汰赛的 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>

【讨论】:

  • 如果 :hover css 是数据绑定的,则很好的答案。
【解决方案2】:

为什么不保持简单。使用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/

【讨论】:

  • 工作完美,谢谢!我仍然希望我理解为什么两个事件处理程序都被调用。但是不要紧。简单在此取胜。
  • @JamesEdwardBrill 您可以通过仅重新定义要更改的属性来进一步简化它。 .black:hover { border-color: green; }.
猜你喜欢
  • 2011-11-07
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 2014-07-09
相关资源
最近更新 更多