淘汰赛:处理 foreach 元素上的事件
Knockout: Handle events on foreach elements
我有以下代码:
<div id="resultlist" data-bind="foreach: content">
<ul style="list-style-type:none;">
<li>
<div class="result" data-bind="event:{ mouseover:myfunction, mouseout:myFunction2}">
<div class ="resultlisticoncontainer">
<div class="resultcontenttypeIcon myclassHidden" data-bind="css: { myclassVisible: newClass() == true, myclassHidden: newClass() == false }">
<object id="contentIcon" data="img/File_Icon_24x24.svg" type="image/svg+xml" width="100%" height="100%"></object>
</div>
<div class="resultcontenttypeIcon myclassHidden" data-bind="css: { myclassVisible: newClass() == true, myclassHidden: newClass() == false }>
<object id="marple" data="img/Glass_Icon_24x24.svg" type="image/svg+xml" width="100%" height="100%"></object>
</div>
</div>
<p><span data-bind="text: name" class="filenamestlye"></span></p>
<p><span data-bind="text: file_path" class="urlstyle"></span></p>
<p><span data-bind="html: highlight" ></span></p>
</div>
</li>
</ul>
</div>
所以我想做的是,当我将鼠标放在 div 和 class "result" 上时,div 和 class "resultcontenttypeIcon" 应该可见。这工作正常,但问题是,这发生在用 foreach 循环创建的每个 div child 上。所以我想要的是,只有悬停的 div 的 div child 变得可见,这样就不会为每个 div 触发事件鼠标悬停。我认为问题在于,newClass 值对于整个视图模型都变为真。
这是我的视图模型代码:
function ItemListViewModel() {
newClass= ko.observable(true);
myfunction = function() {
newClass(true);
},
myFunction2= function(){
newClass(false);
},
}
ko.applyBindings(new ItemListViewModel());
我认为您可能会发现 CSS 更容易实现这一目标。这是一个 JSFiddle,它可以做我认为你想要的。我用图像替换了 objects 以使其在屏幕上工作。显然布局已损坏,因为我们没有您的 CSS.
http://jsfiddle.net/Quango/010vn1ra/
方法很简单:要隐藏的class默认定义为display: none
。
然后我们在 result
class 上添加一个 :hover
来更改 child class 的 display
。这意味着您不需要任何绑定即可执行此操作。
CSS :hover
如果您没有随鼠标悬停在哪个元素上而改变的依赖项,选择器确实可以很好地工作。但是如果你想在其他地方显示带有列表中元素索引的文本,更改模板或触发函数,你仍然需要绑定事件。
由于 Knockout 传递给绑定函数的参数:data
& event
,我们可以阻止事件绑定到 'absorb' 事件的元素。
通过一些目标检查,您的容器鼠标悬停功能如下所示:
app.updateHovered = function(data,e) {
var target = e.target || e.srcElement,
// ko.contextFor passes the context of the object, including the $index observable
index = ko.contextFor(target).$index();
// the following check depends on your elements of course
if (target.nodeName === 'DIV' && target.parentNode.nodeName === 'DIV')
app.isVisible(index); // isVisible holds the currently 'selected index'
}; // and a simple 'false' setter on mouse out
app.removeHovered = function(data, e) {
app.isVisible(false);
}
上面的示例 HTML:
<div data-bind="foreach: list, event: { mouseover: updateHovered, mouseleave: removeHovered }">
<div>
<span data-bind="text: $index, visible: $index() === $parent.isVisible()"></span>
</div>
</div>
<h3 data-bind="text: typeof isVisible() === 'number' ? 'Howdy, you selected item ' + isVisible() : ''"></h3>
查看非常简单的 demo,其中 isVisible
属性 包含最后一个悬停列表项的 $index。
事实上,这是关于委派事件的,因此您可能还想查看 R. Niemeyer 的 Knockout-delegatedEvents 绑定,它会自动为您完成此过程。
我有以下代码:
<div id="resultlist" data-bind="foreach: content">
<ul style="list-style-type:none;">
<li>
<div class="result" data-bind="event:{ mouseover:myfunction, mouseout:myFunction2}">
<div class ="resultlisticoncontainer">
<div class="resultcontenttypeIcon myclassHidden" data-bind="css: { myclassVisible: newClass() == true, myclassHidden: newClass() == false }">
<object id="contentIcon" data="img/File_Icon_24x24.svg" type="image/svg+xml" width="100%" height="100%"></object>
</div>
<div class="resultcontenttypeIcon myclassHidden" data-bind="css: { myclassVisible: newClass() == true, myclassHidden: newClass() == false }>
<object id="marple" data="img/Glass_Icon_24x24.svg" type="image/svg+xml" width="100%" height="100%"></object>
</div>
</div>
<p><span data-bind="text: name" class="filenamestlye"></span></p>
<p><span data-bind="text: file_path" class="urlstyle"></span></p>
<p><span data-bind="html: highlight" ></span></p>
</div>
</li>
</ul>
</div>
所以我想做的是,当我将鼠标放在 div 和 class "result" 上时,div 和 class "resultcontenttypeIcon" 应该可见。这工作正常,但问题是,这发生在用 foreach 循环创建的每个 div child 上。所以我想要的是,只有悬停的 div 的 div child 变得可见,这样就不会为每个 div 触发事件鼠标悬停。我认为问题在于,newClass 值对于整个视图模型都变为真。
这是我的视图模型代码:
function ItemListViewModel() {
newClass= ko.observable(true);
myfunction = function() {
newClass(true);
},
myFunction2= function(){
newClass(false);
},
}
ko.applyBindings(new ItemListViewModel());
我认为您可能会发现 CSS 更容易实现这一目标。这是一个 JSFiddle,它可以做我认为你想要的。我用图像替换了 objects 以使其在屏幕上工作。显然布局已损坏,因为我们没有您的 CSS.
http://jsfiddle.net/Quango/010vn1ra/
方法很简单:要隐藏的class默认定义为display: none
。
然后我们在 result
class 上添加一个 :hover
来更改 child class 的 display
。这意味着您不需要任何绑定即可执行此操作。
CSS :hover
如果您没有随鼠标悬停在哪个元素上而改变的依赖项,选择器确实可以很好地工作。但是如果你想在其他地方显示带有列表中元素索引的文本,更改模板或触发函数,你仍然需要绑定事件。
由于 Knockout 传递给绑定函数的参数:data
& event
,我们可以阻止事件绑定到 'absorb' 事件的元素。
通过一些目标检查,您的容器鼠标悬停功能如下所示:
app.updateHovered = function(data,e) {
var target = e.target || e.srcElement,
// ko.contextFor passes the context of the object, including the $index observable
index = ko.contextFor(target).$index();
// the following check depends on your elements of course
if (target.nodeName === 'DIV' && target.parentNode.nodeName === 'DIV')
app.isVisible(index); // isVisible holds the currently 'selected index'
}; // and a simple 'false' setter on mouse out
app.removeHovered = function(data, e) {
app.isVisible(false);
}
上面的示例 HTML:
<div data-bind="foreach: list, event: { mouseover: updateHovered, mouseleave: removeHovered }">
<div>
<span data-bind="text: $index, visible: $index() === $parent.isVisible()"></span>
</div>
</div>
<h3 data-bind="text: typeof isVisible() === 'number' ? 'Howdy, you selected item ' + isVisible() : ''"></h3>
查看非常简单的 demo,其中 isVisible
属性 包含最后一个悬停列表项的 $index。
事实上,这是关于委派事件的,因此您可能还想查看 R. Niemeyer 的 Knockout-delegatedEvents 绑定,它会自动为您完成此过程。