【问题标题】:jquery click event not firing when using knockout使用淘汰赛时没有触发jquery点击事件
【发布时间】:2012-05-17 09:18:49
【问题描述】:

根据knockout click binding documentation's "Note 3",Knockout 阻止点击事件执行默认功能。要覆盖此行为,我所要做的就是从我的处理函数返回 true。所以,我有这个标记:

<div data-bind="visible:Pages().length == 0">
    <div class="alert alert-info">Click "Parse" button.</div>
    <button class="btn" id="btnParse" title="Parse Tabs">Parse</button>
</div>

现在,我想像这样为按钮附加一个点击事件:

$(function () {       
    $('#btnParse').on('click', function () { alert('clicked'); return true;});
});

请注意,我从函数中返回 true。这个偶数处理程序永远不会触发。我怎样才能做到这一点?

【问题讨论】:

  • 为什么不通过敲除点击绑定添加点击功能?
  • 是的,我可以,而且确实有效。但是,我觉得应该为实际与视图模型相关的东西保留使用数据绑定。如果我想进一步操作页面上的元素,我不应该依靠淘汰赛来做到这一点。我也很恼火一个简单的设置,因为这在应该的时候不起作用。
  • 嗯,你指的是数据绑定点击功能,它不是在谈论 jquery 点击。
  • 我在小提琴中测试了您的确切代码,它工作正常。你必须做其他事情来打破它:jsfiddle.net/tyrsius/YCDt4
  • 我不确定这是一个有效的测试。没有模型,也没有使用淘汰赛。作为直接的 html/jquery 组合,这很好用。使用代码,我可以更改按钮的任何属性值。我只是不能让它触发点击事件。您之前的评论让我尝试将 click 绑定到一个仅返回 true 的函数,以诱使淘汰赛让我触发一个事件。这没有帮助。

标签: jquery knockout.js


【解决方案1】:

您的点击处理程序永远不会触发的原因是它从未应用于您的元素。因此,当您在 jquery 中执行此操作时:

$('.some-class').on('some-event', someFunction);

然后,要绑定到该事件的处理程序,首先 jQuery 必须找到您的 $('.some-class') 选择器。在您的情况下,当您绑定事件时,很可能#btnParse 尚未通过敲除呈现到页面。或者,也有可能,原始元素被渲染、销毁,然后另一个元素被渲染。在第二种情况下,事件处理程序不会保留在按钮上。一种替代方法(我不推荐)是在 DOM 中将处理程序绑定到更高的位置,例如在 document 级别,并将事件过滤到仅具有 id #btnParse 的事件:

$(document).on('click', '#btnParse', function () { console.log('hi'); });

我不建议这样做的原因是因为这是糟糕的淘汰赛做法,您应该像其他一些帖子所建议的那样使用click 绑定。此外,您正在使用 id 属性,这对于模板化的动态内容通常不是一个好主意 - 只需使用类,除非您绝对需要唯一静态元素的 id。

至于如何正确使用 Knockout 的点击绑定,一件棘手的事情是您需要了解 Knockout 如何进行范围界定。例如,如果您在循环内绑定单击,并且您希望主视图模型中的处理程序,则必须引用父范围,因为循环会更改您的上下文:

<!-- ko foreach: someCollection -->
    <a data-bind="click: $parent.someFunction"></a>
<!-- /ko -->

此外,如果您需要更改处理程序执行的 Javascript 上下文(this),那么您需要像这样绑定点击处理程序:

<!-- ko foreach: someCollection -->
    <a data-bind="click: $parent.someFunction.bind($parent)"></a>
<!-- /ko -->

稍微玩一下这些东西,如果您仍然感到困惑,请提出一个新问题。祝你好运!

【讨论】:

    【解决方案2】:

    我认为问题与淘汰赛对您尝试绑定事件的 DOM 的修改有关。要解决此问题,请尝试将 click 函数分配给 parent&lt;div&gt;element。分配单击处理程序时,使用带有选择器的重载来指定您希望仅在单击包含的按钮时处理单击。例如,像这样更改 div:

    <div id="btnContainer" data-bind="visible:Pages().length == 0">
        <div class="alert alert-info">Click "Parse" button.</div>
        <button class="btn" id="btnParse" title="Parse Tabs">Parse</button>
    </div>
    

    然后将您的脚本更改为:

    $(function () {       
        $('#btnContainer').on('click', '#btnParse', function () { alert('clicked');});
    });
    

    请注意,如果 this&lt;div&gt; 包含在另一个修改 DOM 的逻辑块中(模板、foreach 循环等),您可能需要将#btnContainer标签设置为@的第一个祖先987654326@that 不属于此类逻辑块。

    【讨论】:

      【解决方案3】:

      在我的情况下,我正在使用一个 observableArray,它需要将一些 jQuery 魔法应用于该数组中的每个项目。我在自定义绑定方面遇到了一些问题,不想从该数组中的每个项目中获取两个变量。所以,在我的包装中,我将一些黑暗魔法作为一个函数添加到一个不可观察的项目中,这样当点击名称时,我正在处理的地图就会移动到那个位置。

      HTML:

      <ul data-bind="foreach: filteredItems">
          <li class="seat">
              <span class="name" data-bind="text:fullName, click: toggleEmp"></span>
          </li>
      </ul>
      

      代码:

      function viewModel() {
          var vm = this;
          vm.empData = function(data) {
              var emp = this;
              emp.office_x_loc = ko.observable(data.xLoc);
              emp.office_y_loc = ko.observable(data.yLoc);
              emp.toggleEmp = function () {
                  jQuery('#skyLineMap').lhpMegaImgViewer( 'setPosition', emp.office_x_loc(),emp.office_y_loc(), 0.8, false );
          };//*/
      }//*/
      

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        您为点击绑定引用的注释是指您的视图模型中的方法,而不是您的自定义点击处理程序。

        换句话说,如果您在&lt;button&gt; 元素中有一个data-bind="click: doSomething",那么如果您希望它执行您的自定义处理程序,您的视图模型中的doSomething() 方法应该返回true。

        【讨论】:

        • 我确实希望它执行我的自定义处理程序。我什至创建了这个函数: function defaultClick() { return true;并绑定点击按钮来执行它,希望这会让它接受我的处理程序。它没有帮助。
        • 我知道;我并没有暗示你不想。也许您可以发布一个小提琴供我们查看?
        • 默认处理程序不是这里的问题。检查stackoverflow.com/questions/10508916/…,显示类似问题;我怀疑你的 div 被淘汰赛重写了,jquery 不再同步。
        猜你喜欢
        • 1970-01-01
        • 2015-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多