gpt4 book ai didi

jquery - Knockout 和 jQuery 在 IE 8 中冲突?

转载 作者:行者123 更新时间:2023-12-03 23:01:25 24 4
gpt4 key购买 nike

我们在需要支持 IE 8(以及其他几个浏览器)的应用程序中使用 Knockout 和 jQuery。我们有一种情况,需要对一个元素使用 Knockout 单击绑定(bind),对另一个元素使用 jQuery 单击处理程序。然而,我们发现这两种风格的点击处理程序在 IE 8 中相互冲突(它们在我们所有其他支持的浏览器中可以很好地协同工作)。

我们已将问题简化为一个简单的可重现示例。如果您的计算机上没有 IE 8,您可以通过选择“浏览器模式:IE8”在较新版本的 IE 中进行测试:

enter image description here

完成该设置后,您可以在 this jsbin 中查看冲突。 。这段代码是:

<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js"></script>

<script type="text/javascript">
$(document).ready(function () {
ko.applyBindings(function () {
var viewModel = new Object();

viewModel.CanViewPage = true;

viewModel.alertA = function () {
alert("A");
};

$('#B').click(function () {
alert("B");
});

return viewModel;
}());
});
</script>
</head>
<body>
<!-- ko if: CanViewPage -->
<span data-bind="click: alertA">A</span>
<span id="B">B</span>
<!-- /ko -->
</body>
</html>

当您单击“A”时,将显示预期的警报。但是,当您单击“B”时,会错误地调用 alert("A"):

enter image description here

我们找到了两种解决此问题的“解决方案”,但它们都不适合我们的应用程序。让这两个单击处理程序在 IE 8 中同时工作的第一种方法是删除 ko if: CanViewPage。这可以在this jsbin中看到。 。这个“解决方案”是不可行的,因为它是我们在这个大型应用程序的许多页面上使用的核心页面 View 权限机制。

我们发现的第二个“解决方案”是颠倒导入 jQuery 和 Knockout 的脚本标签的顺序。这可以在this jsbin中看到。 。这个“解决方案”也是不可行的,因为这些导入是通过母版页包装器控制的 - 更改它需要大量的 QA 工作来重新测试整个应用程序的错误。

请注意,由于我们必须支持 IE8,因此 jQuery 2.x 或更高版本是 not an option .

考虑到这些限制,有人有其他解决方案吗?谁能解释一下为什么会发生这种情况?

最佳答案

指导

正如您所注意到的,设置 jQuery 事件处理程序和 if 绑定(bind)的组合无法正常工作。如果与 DOM 的所有交互都经过 Knockout,则 Knockout 通常效果最佳。例如,如果我扩展您的示例,使 CanViewPage 最初为 false 但后来变为 true,“B”的事件处理程序就会消失。 http://jsbin.com/uyUTuSa/16/edit

既然您已经声明不能为此事件处理程序使用 Knockout,那么 Bradley 的解决方案是一个很好的解决方法。如果您知道 CanViewPage 永远不会更改(不可观察),您可以使用的另一个解决方案是自定义绑定(bind),它只是清除其错误值的内容,并且不执行任何复制或清理。

ko.bindingHandlers.ifLight = {
init: function(element, valueAccessor) {
if (!valueAccessor()) {
ko.virtualElements.emptyNode(element);
}
}
};
ko.virtualElements.allowedBindings.ifLight = true;

http://jsbin.com/uyUTuSa/18/edit

技术细节

jQuery 通过在元素上设置内部属性来跟踪为元素调用哪个事件处理程序。该属性被分配了一个唯一的编号,用于在某种内部数据存储中查找处理程序。

Knockout if 绑定(bind)首先使用 cloneNode 保存内容元素的副本,然后在该副本上调用 ko.cleanNode,这也会调用jQuery.cleanData。这将从副本中删除所有数据和事件处理程序。

通常情况下,这一切都可以正常工作,但在 Internet Explorer 8(及更低版本)中,“expando”属性会转换为元素属性,并在使用 cloneNode 时进行复制。当 jQuery 清理复制的节点时,事件处理程序数据也会从原始节点中删除。

当 Knockout 为“A”元素添加点击处理程序时,它使用 jQuery 来注册处理程序。 jQuery 似乎重新使用了已清理元素中的数据(和数字),因此“A”元素获得与“B”元素相同的数字。

关于jquery - Knockout 和 jQuery 在 IE 8 中冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20528851/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com