在用户脚本中,我使用 waitForKeyElements()
对元素变化进行了大量检测。 .
但是,我遇到了一个特定示例,其中 waitForKeyElements
不能可靠地触发更改。
我的用户脚本调整 theirID
以插入内部跨度,如您在此处看到的:
<span id='theirID' class='myclass'>
<span class='myclass2'>text</span> more text
</span>
该网站然后更改此代码以删除我的内部跨度,因此它看起来像:
<span id='theirID' class='myclass'>
some text
</span>
出于某种原因,在某些情况下,waitForKeyElements
不会因该更改而被触发。我尝试检测外部跨度、内部跨度、外部跨度的父级、其父级等的变化。
所以我现在想知道是否有其他方法可以检测,例如,带有 myclass2
的元素(内部跨度)是否已经消失?我想我可以轮询 $('.myclass2').length
,但我不知道它从文档中的什么地方消失了。理想情况下,我会知道持有现在丢失的元素的具体 parent 。
有什么想法吗?
最佳答案
这里有两个答案,一个针对这种特定情况(您正在使用 waitForKeyElements
),另一个针对一般情况。
对于这个特定案例:
由于您已经在使用 waitForKeyElements()
,您可以利用节点处理程序中的返回值。
假设目标页面最初有这样的 HTML:
<span id='theirID1' class='myclass'>
Original text 1.
</span>
并且您的脚本使用了 waitForKeyElements()
,如下所示:
waitForKeyElements ("span.myclass", wrapImportantWords);
function wrapImportantWords (jNode) {
var newContent = jNode.text ().replace (/Original/ig, "<span class='myclass2'>My GM</span>");
jNode.html (newContent);
}
产量:
<span class="myclass" id="theirID1">
<span class="myclass2">My GM</span> text 1.
</span>
然后,您可以:
- 让
wrapImportantWords
返回true
-- 这告诉waitForKeyElements
最终没有找到该节点,因此它会继续检查。 - 让该函数同时检查是否(仍然)存在适当的
span.myclass2
。
像这样:
waitForKeyElements ("span.myclass", wrapImportantWords);
function wrapImportantWords (jNode) {
if (jNode.has ("span.myclass2").length == 0) {
var newContent = jNode.text ().replace (/Original/ig, "<span class='myclass2'>My GM</span>");
jNode.html (newContent);
}
return true;
}
通常使用新的 MutationObserver 检测消失的元素:
在您的具体情况下,这似乎有点矫枉过正。但是,这里有一个方法供一般引用。
注意事项:
- 如果你想检测一个节点被删除,你必须在它的parent上设置观察者。当节点本身被删除或完全重写时,突变记录似乎不可用。
在这种情况下,我们想知道span.myclass2
何时被删除,因此我们观察它们的父级 (span.myclass
)。 - > The Mutation Summary library据称使这更容易。
这里是一个完整的 Firefox Greasemonkey 脚本。您可以针对 this page 进行测试. (请注意,Chrome 代码是相同的,除了由于缺少 @require
而进行的常规更改。)
// ==UserScript==
// @name _Node watcher 1
// @include http://jsbin.com/exigal/*
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change introduced
in GM 1.0. It restores the sandbox.
*/
waitForKeyElements ("span.myclass", wrapImportantWords);
function wrapImportantWords (jNode) {
var newContent = jNode.text ().replace (
/Original/ig, "<span class='myclass2'>My GM</span>"
);
jNode.html (newContent);
}
/*--- Start of Mutation observer code...
*/
var targetNodes = $("span.myclass");
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var myObserver = new MutationObserver (mutationHandler);
var obsConfig = {
childList: true, characterData: true, attributes: true, subtree: true
};
//--- Add a target node to the observer. Can only add one node at a time.
targetNodes.each ( function () {
myObserver.observe (this, obsConfig);
} );
function mutationHandler (mutationRecords) {
mutationRecords.forEach ( function (mutation) {
if ( mutation.type == "childList"
&& typeof mutation.removedNodes == "object"
) {
var remdNodes = $(mutation.removedNodes);
if (remdNodes.is ("span.myclass2") ) {
console.log ("Desired node was deleted! Restoring...");
var targNode = $(mutation.target);
wrapImportantWords (targNode);
}
}
} );
}
关于javascript - 如何使用 jQuery 检测 HTML 元素是否消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12589524/