Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript js似乎在攻击我的jQuery事件处理程序,多么粗鲁_Javascript_Jquery_Knockout.js - Fatal编程技术网

Javascript js似乎在攻击我的jQuery事件处理程序,多么粗鲁

Javascript js似乎在攻击我的jQuery事件处理程序,多么粗鲁,javascript,jquery,knockout.js,Javascript,Jquery,Knockout.js,好吧,我已经试着解开这个烂摊子好几个小时了,但一无所获,就像一只狗在追它的尾巴一样。情况是这样的 我正在使用Knockout.js作为我的UI,它本身就非常好用。然而,我试图使用一些第三方代码,使下拉列表和复选框看起来都很漂亮。实际上,我甚至不确定这是第三方库还是我们的设计师写的东西。这段代码隐藏了真实的复选框,并将其替换为通过CSS模拟复选框的假的。span的单击事件触发real复选框的更改事件: // this code updates the fake UI this._changeEve

好吧,我已经试着解开这个烂摊子好几个小时了,但一无所获,就像一只狗在追它的尾巴一样。情况是这样的

我正在使用Knockout.js作为我的UI,它本身就非常好用。然而,我试图使用一些第三方代码,使下拉列表和复选框看起来都很漂亮。实际上,我甚至不确定这是第三方库还是我们的设计师写的东西。这段代码隐藏了真实的复选框,并将其替换为通过CSS模拟复选框的假的
。span的
单击
事件触发real复选框的
更改
事件:

// this code updates the fake UI
this._changeEvent = function() {
    self.isChecked = self.$input.is(':checked');
    self._updateHTML(false, true);
    jQuery(self).trigger('change');
};

// when the user clicks the fake checkbox, we trigger change on the real checkbox
this.$fake.on('click', function(e) {
    e.preventDefault();
    self.$input.click().trigger('change');
});

// Bind _changeEvent to the real checkbox
this.$input.change(this._changeEvent);
这实际上适用于Knockout.js,因为Knockout将侦听该事件处理程序。换句话说,当用户单击fake复选框时,绑定的淘汰模型将得到更新。但是,不起作用的是更新模型。如果我打电话:

model.SomeValue(!curValue); // SomeValue is bound to a checkbox, flip its value
模型得到更新,但假UI没有更新。我将此问题追溯到
ko.bindingHandlers.checked.update中的代码,它执行以下操作:

// When bound to anything other value (not an array), the checkbox being checked represents the value being trueish
element.checked = value;
基本上,设置了
元素.checked
属性,但不触发任何事件。因此,永远不会调用
\u changeEvent
函数。因此,我实现了自己的
ko.bindingHandlers.checked.update
函数,它是内置函数的副本。理论上,这就是我需要做的:

   ko.bindingHandlers.checked.update = function (element, valueAccessor)
   {
      var value = ko.utils.unwrapObservable(valueAccessor());

      if (element.type == "checkbox")
      {
         if (value instanceof Array)
         {
            // When bound to an array, the checkbox being checked represents its value being present in that array
            element.checked = ko.utils.arrayIndexOf(value, element.value) >= 0;
         }
         else
         {
            // When bound to anything other value (not an array), the checkbox being checked represents the value being trueish
            //element.checked = value;
            $(element).prop('checked', value).trigger('change'); // <--- this should work!
         }
      }
      else if (element.type == "radio")
      {
         element.checked = (element.value == value);
      }
   };
ko.bindingHandlers.checked.update=函数(元素,值访问器)
{
var value=ko.utils.unwrapobbservable(valueAccessor());
如果(element.type==“复选框”)
{
if(数组的值实例)
{
//绑定到数组时,选中的复选框表示该数组中存在的值
element.checked=ko.utils.arrayIndexOf(value,element.value)>=0;
}
其他的
{
//当绑定到任何其他值(不是数组)时,选中的复选框表示该值为true
//element.checked=值;

$(element).prop('checked',value.).trigger('change');//尝试触发并侦听自定义事件:

element.checked = value;
element.dispatchEvent(new Event("forcedChange"));

尝试将复选框对象创建为jQuery插件,并创建淘汰自定义绑定,将其绑定到viewmodel。 我已经建立了一个JSFIDLE,它可以做到这一点:

(我不得不添加这个代码段,或者我的答案不被接受,请参阅JSFIDLE以获取完整的代码示例)。 很抱歉,看起来有很多代码,但是插件部分最初是一个独立的jquery插件,后来添加了淘汰绑定,其中一些代码已经被淘汰绑定所淘汰。 它可以放在自己的文件中以减少混乱。
创建自定义绑定在knockout网站上有文档记录。

只是头脑风暴,但是这个第三方控件是使用事件名称空间开发的吗?可能就像你所说的,knockout和这个控件正在以某种方式争夺默认的“更改”事件。当我开发小部件和应用程序时,我总是使用事件名称空间n使用jQuery绑定事件

使用“myWidget”命名空间的示例:

$('#element').on('change.myWidget', function(e) {
  // handle the event
}

不过,我可能会完全偏离基准。

只是一个简单的想法。您的设计师似乎触发了这一行中的点击和更改事件:

self.$input.click().trigger('change');
这难道不是可以尝试的吗?可能它绑定到单击事件而不是更改事件?请在you else语句中尝试以下内容:

$(element).prop('checked', value).click().trigger('change'); // <--- this should work!

$(element).prop('checked',value.).click().trigger('change');//只需创建自己的自定义绑定来更新UI,而不是覆盖基本的选中处理程序

下面是一个用于处理更新UI的模型和自定义绑定的示例:

var Model = function () {
    this.checked = ko.observable(false);
};

ko.bindingHandlers.customCheckbox = {
    init: function (element) {
        // Create the custom checkbox here
        $(element).customInput();
    },
    update: function (element) {
        // Update the checkbox UI after the value in the model changes
        $(element).trigger('updateState');
    }
};
我将模型绑定到以下HTML:

<input type="checkbox" name="genre" id="check-1" value="action" data-bind="checked: checked, customCheckbox: checked" />

真的,这就是我需要做的

下面是一个例子:


[编辑]-我想我匆匆读完了你的问题,没有理解你所问的问题的关键。无论如何,我会把我的答案留在这里。

听起来你遇到的问题似乎不是由于击倒事件和另一组代码(例如,更改复选框的CSS)的冲突造成的但是由于Javascript线程和线程中的事件在处理方式上存在冲突

Javascript在浏览器中作为单个线程进行处理:所有进程都按顺序运行,任何中断该顺序的事件都可能导致事件失败。如果您可以独立调用每个函数,但在脚本中同时包含这两个函数时会出现干扰,则会出现onclick或onmousedown事件,触发t的CSS更改复选框可能会干扰淘汰脚本。在这个“单一线程”中,所有事件都会影响另一个线程的执行,甚至鼠标移动

这个()示例使用计时器演示了这个想法,但我认为您当前的情况也可能遇到同样的问题

要解决此问题,您可以编写一个简短的函数,例如:

函数doBoth(checkboxid){

$(“#checkboxid”).addclass(“预检查”)

$(“#checkboxid”).prop('checked',true)

}

重要的一点是,每个动作都是按顺序进行的,没有鼠标事件中断的可能性


希望这能有所帮助!

+1真是太粗鲁了:)+1对于一个写得很好的问题。还没有深入研究过这个问题,但是浏览一下KO源代码,我确实看到,
RegisterEventHandler
in对涉及jQuery时复选框的特殊处理有相当长的评论。也许这是一个线索?@Esailija-是的,我想我必须构建一个完全独立的可复制示例。叹气。当使用jQuery时,输入的顺序是结论很重要。只有当包含Knockout时,Knockout才使用jQuery。@Jeroen-您可能是对的,正如最后一行注释所述:“//通过插入处理程序并在我之前应用正确的检查来修复此问题。”
<input type="checkbox" name="genre" id="check-1" value="action" data-bind="checked: checked, customCheckbox: checked" />