【问题标题】:adding event handlers with jquery independently of knockoutjs bindings使用 jquery 独立于 knockoutjs 绑定添加事件处理程序
【发布时间】:2012-08-05 01:27:34
【问题描述】:

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

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

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

在我的 DOM 初始化之后,但这不起作用,因为 knockoutjs 绑定替换了我绑定滚动事件的元素。是否有相当于.live() 的滚动功能?或者,是否有另一种方法可以将我的事件处理程序动态注入不依赖于静态编码属性的敲除绑定机制?

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

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

【问题讨论】:

    标签: jquery knockout.js


    【解决方案1】:

    我最终实现了以下模式:

    在我的模板中:

    <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');
    });
    

    不像我想要的那样解耦,但比显式引用更好。

    【讨论】:

      【解决方案2】:

      来自quirksmode,似乎“滚动”事件没有冒泡,所以我认为事件委托不会起作用。

      您可以使用 foreach 绑定的剔除“afterAdd”和“afterRender”回调(在 foreach documentation page 的注释 5 中记录)有条件地绑定到滚动事件,具体取决于您是否要进行日志记录。

      【讨论】:

      • 我想这意味着我的淘汰代码必须知道我正在尝试执行的日志记录...我希望将它们分开。
      【解决方案3】:

      您可以尝试将事件处理委托给敲除不会弄乱的静态容器。在最顶层,选择的容器可以是document

      .live() 自 jQuery 1.7.1 起已弃用,但使用 on() 可以达到相同的效果。

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

      有了这个,任何&lt;ul class="doclist"&gt; 元素都将具有日志记录操作,无论它是在附加处理程序时到位,还是稍后到位。

      我承认我从来不需要委托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 替换为更多本地化容器的选择器。

      【讨论】:

      • 我应该补充一点,我现在卡在使用 jQuery 1.4.4。
      • 但是,我刚刚看到@bmode 的回答。滚动不冒泡,经过反思,这是有道理的 - DOH!
      【解决方案4】:

      如果您想进行委托注册,请选择一个始终存在的元素(我将在示例中使用body,但尽可能选择最接近目标元素的元素)并执行以下操作:

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

      对于 jQuery 1.4.4

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

      【讨论】:

      • 我应该补充一点,我现在卡在使用 jQuery 1.4.4。
      • 我认为它应该工作相同,只是使用delegate()而不是on(),并且需要不同的参数顺序。
      • 我根本无法让delegate() 处理scroll 事件; @bmode 的回答表明它不起作用。
      猜你喜欢
      • 2013-01-27
      • 1970-01-01
      • 2012-01-18
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      • 1970-01-01
      相关资源
      最近更新 更多