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