- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个 Chrome 扩展,它可能会改变数千个 DOM 元素。出于性能原因,我想在内存中执行此操作,而不是重复触摸 DOM。 jQuery's clone
正如您在下面的代码片段中看到的那样,对此非常有效。
$(document).ready(function() {
$("#click-me").on("click", () => {
$("#click-count").html((idx, num) => ++num)
})
$("#with-cloning").click(function() {
withCloning(($elem) => {
$elem.find("h1").text("changed with cloning (still works)")
})
})
$("#without-cloning").click(function() {
withoutCloning(($elem) => {
$elem.find("h1").text("changed without cloning (still works)")
})
})
})
function withCloning(mutateDom) {
var $elem = $("body")
// The `true` arg keeps bindings
var $cloned = $elem.clone(true)
mutateDom($cloned)
$elem.replaceWith($cloned)
}
function withoutCloning(mutateDom) {
mutateDom($("body"))
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="wrapper">
<h1 id="click-me">Click me!</h1>
<p>Click count: <span id="click-count">0</span></p>
</div>
<button id="without-cloning">replace without cloning</button>
<button id="with-cloning">replace with cloning</button>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>
当我在 Chrome 扩展中使用这个完全相同的函数时,它成功替换了内容,但破坏了所有事件处理程序。
以下函数在嵌入网站(和代码片段)和我的 Chrome 扩展程序中时都可以完美运行:
function withoutCloning(mutateDom) {
mutateDom($("body"))
}
如何使 withCloning
函数在 Chrome 扩展程序中正确运行(如代码片段中所示)?
jQuery clone docs如此描述 clone
的可选参数:
A Boolean indicating whether event handlers should be copied along with the elements. As of jQuery 1.4, element data will be copied as well.
如果有其他更合适的东西(也许是文档片段),我不会以任何方式依赖于使用 jQuery 的克隆
。
我通过传入 $elem => $elem
验证了冲突与 mutateDom
函数无关。问题依然存在。
最佳答案
您正在做的事情预计会破坏事件处理程序。您无法克隆事件处理程序,除了通过 jQuery 方法添加的事件之外,还可以使用 jQuery 方法进行克隆或替换。因此,用克隆副本替换 DOM 的内容将导致删除事件处理程序。
.clone()
无法克隆非 jQuery 事件当事件监听器不是通过 jQuery 方法添加时,jQuery 无法知道元素上发生了什么事件。因此,通过普通 DOM 方法(即 .addEventListener()
)添加的任何事件都不会被 jQuery 的 .clone()
克隆。 .
这是一个使用 addEventListener()
添加计数事件处理程序的示例。你可以看到 jQuery .clone()
不克隆它,但克隆 jQuery 事件(也 available on JS Bin ):
$(document).ready(function() {
document.querySelector("#click-me").addEventListener("click", () => {
$("#click-count").html((idx, num) => ++num)
})
$("#with-cloning").click(function() {
withCloning(($elem) => {
$elem.find("h1").text("changed with cloning (counting does not work)")
})
})
$("#without-cloning").click(function() {
withoutCloning(($elem) => {
$elem.find("h1").text("changed without cloning (still works)")
})
})
})
function withCloning(mutateDom) {
var $elem = $("body")
// The `true` arg keeps bindings
var $cloned = $elem.clone(true)
mutateDom($cloned)
$elem.replaceWith($cloned)
}
function withoutCloning(mutateDom) {
mutateDom($("body"))
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="wrapper">
<h1 id="click-me">Click me!</h1>
<p>Click count: <span id="click-count">0</span></p>
</div>
<button id="without-cloning">replace without cloning</button>
<button id="with-cloning">replace with cloning</button>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>
这在您的 JS Bin 中起作用的原因是您使用 jQuery 添加了所有事件处理程序。 jQuery 实际上保留了您通过 jQuery 添加的事件处理程序的记录,并且能够在您.clone()
时克隆 jQuery 添加的事件以及元素。元素,或使用 .replaceWith()
来替换该元素。 jQuery 事件处理程序的恢复发生在两者 .clone()
和 .replaceWith()
。换句话说,即使使用正常的 JavaScript 方法( node.cloneNode()
或 Node.replaceChild()
)执行这两个操作之一,而使用 jQuery 的方法( .clone()
和 .replaceWith()
)执行另一个操作,jQuery 也会恢复您所发生的事件。使用 jQuery 添加。您可以使用以下代码片段来尝试使用 jQuery 与普通 JavaScript 的组合进行克隆并替换元素 ( also on JS Bin ):
$(document).ready(function() {
$("#click-me").on("click", () => {
$("#click-count").html((idx, num) => ++num);
});
$("#with-cloning").click(function() {
withCloning(($elem) => {
$elem.find("h1").text("changed with cloning (still works)");
});
});
$("#without-cloning").click(function() {
withoutCloning(($elem) => {
$elem.find("h1").text("changed without cloning (still works)");
});
});
});
function withCloning(mutateDom) {
var $elem = $("body")
var used='Used:';
var $cloned;
if($('#useClone').is(':checked')){
//jQuery clone. The `true` arg keeps bindings
$cloned = $elem.clone(true);
used += ' clone()';
} else {
//Vanilla JavaScript cloneNode. `true` makes a deep copy
$cloned = $($elem[0].cloneNode(true));
used += ' cloneNode()';
}
mutateDom($cloned);
if($('#useReplaceWith').is(':checked')){
//jQuery replaceWith
$elem.replaceWith($cloned);
used += ' and replaceWith()';
} else {
//Vanilla JavaScript replaceChild
$elem[0].parentNode.replaceChild($cloned[0],$elem[0]);
used += ' and replaceChild()';
}
console.log(used);
}
function withoutCloning(mutateDom) {
mutateDom($("body"));
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="wrapper">
<h1 id="click-me">Click me!</h1>
<p>Click count: <span id="click-count">0</span></p>
</div>
<button id="without-cloning">replace without cloning</button>
<button id="with-cloning">replace with cloning</button></br></br>
Use:</br>
<table>
<tr><td>jQuery</td><td>vanilla JavaScript</td></tr>
<tr>
<td><input name="cloneType" type="radio" id="useClone" checked="true">`.clone(true)`</input></td>
<td><input name="cloneType" type="radio" id="useCloneNode">`.cloneNode(true)`</input></td>
</tr>
<tr>
<td><input name="replaceType" type="radio" id="useReplaceWith" checked="true">`.replaceWith()`</input></td>
<td><input name="replaceType" type="radio" id="usereplaceChild">`.replaceChild()`</input></td>
</tr>
</table>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>
请注意,一旦您使用 .cloneNode()
进行克隆, ,如果您尝试使用 .clone(true)
再次克隆,事件不会被克隆。
关于javascript - `$().clone(true)` 破坏 Chrome 扩展中的事件处理程序(适用于 jsbin),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41198843/
我正在尝试完成撤消/重做。我正在使用loadFromJSON(...)从我存储在数组中的 Canvas 状态重新构建 Canvas 。基本上,我的想法是破坏现有的 Canvas 并重新构建 Canva
在某些情况下,我有一个在 iframe 中打开的网页。当它被加载到那个 iframe 中时,我需要它将窗口位置设置为资源以下载文件(所有这些都是为了更新 GreaseMonkey 脚本......所有
当我创建 Intent 时: Intent in = new Intent(this, myclass.class); this.startActivity(in); 我创建了一个新的 Intent
我正在我本地版本的 Wordpress 网站上为 Wordpress 创建新的短代码。 在 functions.php 中,我添加了例如: function shortTest() { re
我正在为机械网站制作 JavaScript 闪卡游戏。因为我想将方程写在卡片上,所以我需要使用 delta(Δ) 符号。 一张卡片可能有:一侧是“功率方程”,另一侧是“P=W/Δt”。如果卡片从第一面
我编写了以下代码: document.addEventListener("DOMContentLoaded", ()=>{ let menu = document.querySelector(
我的浏览器同步工作正常,但我仍然很难处理之前的 html 的缓存。即使选中了 Chrome 的“禁用缓存”,甚至在隐身模式下也是如此! 要加载页面更改,我总是必须“清除缓存并硬重新加载”。 我想知道,
我注意到每次打开和关闭(通过单击菜单项或单击菜单外的某个区域)时,上下文菜单 ( Ext.menu.Menu ) s 不会从 DOM 中删除,它们只是以某种方式变得不可见。 如何改变这个? 最佳答案
给定依赖记录类型: Record FinPath : Type := mkPath { fp_head : S i; fp_tail
在 Husdon/Jenkins 中,我可以在构建被破坏时设置通知,以向进行破坏构建的 checkin 的用户发送电子邮件。如何在 Teamcity 中执行此操作? 我知道个人用户可以通过 Teamc
我注意到每次打开和关闭(通过单击菜单项或单击菜单外的某个区域)时,上下文菜单 ( Ext.menu.Menu ) s 不会从 DOM 中删除,它们只是以某种方式变得不可见。 如何改变这个? 最佳答案
使用 MIMEMultipart('alternative') 发送 html 和 pain-text 时 将 html 转换为文本时,html 的 anchor 换行 http://127.0.0.
每当我的应用程序最小化时,我都会启动一个服务,该服务向我的 HTTP 服务器发送拉取请求以检查通知,当应用程序恢复时,服务将被终止(以及计划的可运行项)。一切正常,直到我决定终止该应用程序(将其从正在
我意识到该框架处于 alpha 阶段,但正在实现 jQuery Mobile破坏了我的omniauth 身份验证。当我尝试登录时,一旦我尝试点击/auth/twitter Controller ,jQ
我对 Angular 比较陌生,经过几个小时的调试,我发现添加 jquery 时存在一些不兼容性。该指令在没有 jquery 的情况下工作正常,但在使用 jquery 时会中断:/ 这是一个 plnk
我发现,因为我正在处理的所有表单都有一个包含“name =“submit””属性的提交按钮,所以当我单击应该触发表单提交的链接时,触发器提交会中断. 有谁知道我该如何解决这个问题。 下面的 JQuer
我遇到了一个问题:/我得到了一个 CSS 东西,它使悬停时背景位置发生变化。但是当我在 javascript 中运行一个改变悬停的函数后,CSS 停止工作。 这是函数: function tree()
谁能给出一个完整的例子来说明 qooxdoo 1.6 中的 dispose 和 destruct 是如何工作的? ,我在 qooxdoo 演示或文档中找不到任何好的示例。 谢谢你的建议。 最佳答案 处
我对 JFormattedTextField 有疑问(我将它用作我们所有文本字段的基类)。 今天我尝试向该字段的文档添加一个文档过滤器,它工作得很好,但前提是它没有设置格式化程序工厂。 问题是,当设置
我有一个点击事件 $('#ship_Move').click(function (event) { event.stopPropagation();
我是一名优秀的程序员,十分优秀!