【问题标题】:Knockout: Handle events on foreach elements淘汰赛:处理 foreach 元素上的事件
【发布时间】:2015-01-29 11:23:31
【问题描述】:

我有以下代码:

<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>

所以我想要做的是,当我将鼠标放在具有“result”类的 div 上时,具有“resultcontenttypeIcon”类的 div 应该可见。这很好用,但问题是,这发生在使用 foreach 循环创建的每个 div 子项上。所以我想要的是,只有悬停的 div 的 div 子项变得可见,因此不会为每个 div 触发事件 mouseover。我认为问题在于,newClass 值对于整个视图模型都是正确的。

这是我的视图模型代码:

function ItemListViewModel() {

    newClass= ko.observable(true);
    myfunction = function() {
        newClass(true);

    },
    myFunction2= function(){
        newClass(false);         
    },
}
ko.applyBindings(new ItemListViewModel());

【问题讨论】:

  • 您是否考虑过只使用 CSS :hover 类来隐藏/显示结果?它会更简单,更快。
  • 谢谢,这就行了。我给了“结果” div :hover .resultcontenttypeIcon {display: block; } style 和 resultcontenttypeIcon 样式显示:无;。因此,如果我将鼠标悬停在“结果”上,则会显示子 div。

标签: javascript html knockout.js


【解决方案1】:

我认为您可能会发现 CSS 更容易实现这一点。这是一个 JSFiddle,它可以满足我的需求。我已经用图像替换了对象以使其在屏幕上工作。显然布局被破坏了,因为我们没有你的 CSS。

http://jsfiddle.net/Quango/010vn1ra/

方法很简单:要隐藏的类默认定义为display: none

然后我们在 result 类上添加一个 :hover 来更改子类的 display。这意味着您不需要任何绑定来执行此操作。

【讨论】:

  • 也谢谢你。是否已经将其更改为 css 样式版本。效果很好。
【解决方案2】:

CSS :hover 选择器确实可以很好地工作,如果您没有任何依赖项会随着悬停在哪个元素上而改变。但是,例如,如果您想在其他地方显示带有列表中元素索引的文本,更改模板或触发功能,您仍然需要绑定事件。

由于 Knockout 传递给绑定函数的参数:dataevent,我们可以防止事件绑定到的元素“吸收”事件。 通过一些目标检查,您的容器鼠标悬停功能如下所示:

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 绑定,它会为您自动执行此过程。

【讨论】:

    猜你喜欢
    • 2014-05-29
    • 2015-03-17
    • 2014-04-28
    • 1970-01-01
    • 2018-02-27
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    相关资源
    最近更新 更多