使用jquery添加事件处理程序,独立于knockoutjs绑定

时间:2012-08-08 00:25:25

标签: jquery knockout.js

我有一个<ul>元素,其中填充了foreach绑定。这个<ul>在不同的时间重新创建,因为它所嵌入的模板被重新渲染。这很好。

但是,在某些情况下,我想在knockoutjs之外向此列表添加其他行为(例如,记录滚动事件)。我不希望这段代码成为绑定的一部分,因为它只是有条件地注入(例如,在运行实验时)。我以为我可以做像

这样的事情
$('ul.doclist').scroll(function() { 
    // log scrolling here
});
在我的DOM初始化之后

,但这不起作用,因为knockoutjs绑定替换了我绑定scroll事件的元素。是否有相当于.live()的滚动?或者,是否有另一种方法可以动态地将我的事件处理程序注入到不依赖于静态编码属性的knockout绑定机制中?

编辑:2012年8月7日下午5:41:我尝试使用delegate()方法,但无法弄清楚如何指定选择器来查找深层嵌套的ul

编辑:2012年8月7日下午6:31:我正在使用jquery 1.4.4并在Chrome中进行测试。

4 个答案:

答案 0 :(得分:2)

我最终实施了以下模式:

在我的模板中:

<ul class="doclist" data-bind='foreach: rows, event: {scroll: window.viewModel.notifyOfScrollEvent}'>
</ul>

在我的视图模型中:

this.documentScrolled = ko.observable();
this.notifyOfScrollEvent = function() {
    self.documentScrolled.valueHasMutated();
}

在我的条件代码中:

viewModel.documentScrolled.subscribe(function() {
    console.log('scrolling');
});

不像我喜欢的那样去耦合,但比明确的参考更好。

答案 1 :(得分:1)

您可以尝试将事件处理委派给一个静态容器,该容器不会破坏。在最顶层,所选容器可以是document

自jQuery 1.7.1以来,

.live()已被弃用,但使用on()可以实现相同的效果。

$(document).on('scroll', 'ul.doclist', function() { 
    // log scrolling here
});

有了这个,任何<ul class="doclist">元素都将具有日志记录操作,无论它在附加处理程序时是否存在,或者稍后放置。

我承认我从未需要委派scroll,但原则上这应该有效,提供实际发生的'滚动'事件(编辑 - 并且它起泡)。

修改

以下是等效的:

$(selector).live(events, data, handler);                // jQuery 1.3+
$(document).delegate(selector, events, data, handler);  // jQuery 1.4.3+
$(document).on(events, selector, data, handler);        // jQuery 1.7+

因此,上面的表达式将转换为:

$(document).delegate('ul.doclist', 'scroll', function() { 
    // log scrolling here
});

如果可能,请将document替换为更多本地化容器的选择器。

答案 2 :(得分:1)

quirksmode开始,&#34;滚动&#34;事件没有泡沫,所以我不认为事件授权会起作用。

你可以使用淘汰赛&#34; afterAdd&#34;和&#34; afterRender&#34; foreach绑定的回调(记录在foreach documentation page上的注释5中)有条件地绑定到滚动事件,具体取决于您是否要进行日志记录。

答案 3 :(得分:0)

如果要进行委托注册,请选择一个始终存在的元素(我将在示例中使用body,但选择最接近目标元素的元素)并执行类似的操作这样:

$( "body" ).on( 'scroll', 'ul.doclist', handler );

对于jQuery 1.4.4

$( "body" ).delegate( 'ul.doclist', 'scroll', handler );