我有一个由 Knockout.js foreach
数据绑定填充的图像网格。默认情况下,网格中的每个图像都有一个由背景颜色设置的黑色轮廓。当用户将鼠标悬停在每个图像上时,我希望该轮廓变为白色以表示它已被突出显示。
目前,我正在使用两个事件处理程序,一个用于mouseenter
,一个用于mouseleave
。
第一个将图像的 CSS 类更改为具有白色背景的类。后者将其改回黑色。但是,当鼠标进入图像时,两者都会被调用(通过调试确认),因此看不到任何更改。
该网页如下所示:(注意:每个图像都有一个表示图像文件位置的fileName
属性。有两个CSS
类称为black
和white
,每个高亮状态对应一个。
<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) 为什么鼠标进入图像时同时调用mouseenter
和mouseleave
?
(B) 实现所需突出显示功能的更简单方法是什么?
Knockout 的目的是通过绑定处理程序以声明方式将视图(您的 HTML)连接到您的视图模型(JavaScript 对象)。但是,并非每个可能的 DOM 到视图模型交互都具有预定义的绑定处理程序。
在您的特定情况下(更改样式),您可以简单地使用 :hover
CSS 伪类。您的视图会响应鼠标移动,但您的视图模型不会注意到任何这些。
如果要更改不同的 DOM 属性以响应鼠标移动,例如元素的文本,CSS 将不再起作用。您可以"手动"使用 KNOCKOUT 的event
绑定 - 也可以创建自定义绑定处理程序,用于设置视图模型的属性之一以响应 mouseenter 和mouseleave 事件。
自定义绑定处理程序的优点是,您现在有一个可以基于其他行为的实际可观察量,并且您在视图中要执行的键入更少,这在多次使用它时非常有用。
悬停时,以下内容会更改元素的文本和 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/