单击事件停止 MutationOberserver
Stop MutationOberserver on click event
我有一个动态的 DOM 结构,其中节点始终被插入和删除,以便对新节点做出反应我使用的是 MutationObserver,当用户单击 Button 时它会被激活。每次用户单击该按钮时,MutationObserver 都会 运行 两个函数,当我观察到的 DOM 结构发生变化时,这些函数将保持 运行ning。
我想要做的是在用户再次单击按钮时立即断开 MutationObservers(假设第一次单击然后对元素进行排序,再次单击并停止对元素进行排序)。每次用户单击按钮时,我都会传递一个布尔值 (goSortDom)(如果为真,请执行操作并观察,如果为假,则停止观察)。问题是,当我尝试在 goSortDom=false 时断开观察者的连接时,它们永远不会断开连接,并且函数将保持 运行ning.
我对 mutationObservers 很陌生,所以我不知道我的方法是否是一种不好的做法,这就是为什么我也非常感谢对此的评论。
$(document).ready(function () {
// Function 1: Assign Priorities
function assignChatPriority(arrayParent) {
//Assign Priorities
//Observe if time change, if change re-assign priority to dom node
timeInQueueDomObserver.observe(
$(incomingChat).find(".time_cell")[0],
configtimeInQueue
}
// Function 2: Reorder DOM
function orderIncomingChats() {
//Reorder DOM save DOM elements to Array
//Replace original DOM with new sorted DOM
}
//Declaring DOM Observers for Time in Queue and DOM container dynamics
var incomingChatsDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.addedNodes.length) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
if (
mutation.addedNodes[i].attributes["data-priority"] === undefined
) {
runExtensionFunctions();
}
}
}
});
});
var timeInQueueDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (
mutation.addedNodes.length === 1 &&
mutation.addedNodes[0].nodeType === Node.TEXT_NODE &&
mutation.removedNodes.length === 1 &&
mutation.removedNodes[0].nodeType === Node.TEXT_NODE
) {
runExtensionFunctions();
}
});
});
//Obervers Configuration
let configChatsContainer = {
childList: true,
};
let configtimeInQueue = {
childList: true,
};
if (goSortDom) {
//boolean is true go ahead run functions and observe
assignChatPriority(incomingChatsRows);
orderIncomingChats();
incomingChatsDomObserver.observe(
incomingChatsContainer[0],
configChatsContainer
);
} else {
//disconnect observers: WON'T WORK
incomingChatsDomObserver.disconnect();
timeInQueueDomObserver.disconnect();
}
}
您的代码似乎无法识别 (goSortDom) 单击事件。您是否尝试过将该代码字符串添加到您的按钮单击事件中?
Vue.js 框架可能非常适合您的要求。除此之外,我能告诉你的和你知道的一样。当 dom 元素动态改变时,Javascript 行为非常奇怪。我有一个应用程序,该应用程序的选择数量呈指数级增长,这些选择是根据之前的选择加载的。每次加载新信息时,我都必须特别注意用于操作数据的选择器。否则,无论 Id 或 class 选择器如何,JS 都无法使用新导入的数据。我还必须使用 .on( events [ selector ] [ data ] ) Javascript 函数而不是 .click() jquery 函数来完成工作。特别是确保填写了选择器信息。
$("#myDiv").on('click', '.MyDivClass', function(){'Select All and return information'};
您在传递给 .ready() 的函数中初始化并处理 MutationObserver 的 incomingChatsDomObserver
和 timeInQueueDomObserver
。我没有看到外部参考。如果是这种情况,if (goSortDom)
只会对初始化的 MutationObserver 进行一次评估。之后,函数结束,引用丢失。再次调用该函数会创建 new MutationObserver,并且 disconnect() 调用将引用那些新的 MutationObserver,而不是已经观察到的旧 MutationObserver!
难道你想达到的目的是把MutationObserver的初始化和引用移到这个函数外面去用?或者可能会断开 MutationObservers 内部的连接?
让我试一试。由于这不是完整的代码,我无法自己测试它:
- 想法(移动参考):
// ANSWERER: Now the references are outside the ready function. If the ready function is done, this references still exist.
//Declaring DOM Observers for Time in Queue and DOM container dynamics
var incomingChatsDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.addedNodes.length) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
if (
mutation.addedNodes[i].attributes["data-priority"] === undefined
) {
runExtensionFunctions();
}
}
}
});
});
var timeInQueueDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (
mutation.addedNodes.length === 1 &&
mutation.addedNodes[0].nodeType === Node.TEXT_NODE &&
mutation.removedNodes.length === 1 &&
mutation.removedNodes[0].nodeType === Node.TEXT_NODE
) {
runExtensionFunctions();
}
});
});
// ANSWERER: This is now possible
function disconnectObservers() {
incomingChatsDomObserver.disconnect();
timeInQueueDomObserver.disconnect();
}
$(document).ready(function () {
// Function 1: Assign Priorities
function assignChatPriority(arrayParent) {
//Assign Priorities
//Observe if time change, if change re-assign priority to dom node
timeInQueueDomObserver.observe(
$(incomingChat).find(".time_cell")[0],
configtimeInQueue
}
// Function 2: Reorder DOM
function orderIncomingChats() {
//Reorder DOM save DOM elements to Array
//Replace original DOM with new sorted DOM
}
//Obervers Configuration
let configChatsContainer = {
childList: true,
};
let configtimeInQueue = {
childList: true,
};
if (goSortDom) {
//boolean is true go ahead run functions and observe
assignChatPriority(incomingChatsRows);
orderIncomingChats();
incomingChatsDomObserver.observe(
incomingChatsContainer[0],
configChatsContainer
);
} else {
//disconnect observers: WON'T WORK
incomingChatsDomObserver.disconnect();
timeInQueueDomObserver.disconnect();
}
}
- 版本。 MutationObserver 断开连接:
$(document).ready(function () {
// Function 1: Assign Priorities
function assignChatPriority(arrayParent) {
//Assign Priorities
//Observe if time change, if change re-assign priority to dom node
timeInQueueDomObserver.observe(
$(incomingChat).find(".time_cell")[0],
configtimeInQueue
}
// Function 2: Reorder DOM
function orderIncomingChats() {
//Reorder DOM save DOM elements to Array
//Replace original DOM with new sorted DOM
}
//Declaring DOM Observers for Time in Queue and DOM container dynamics
var incomingChatsDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.addedNodes.length) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
if (
mutation.addedNodes[i].attributes["data-priority"] === undefined
) {
runExtensionFunctions();
}
}
}
});
// ANSWERER: Now the observer disconnects itself after the run. Remember: MutationObserver's disconnect itself from *everywhere*
incomingChatsDomObserver.disconnect();
});
var timeInQueueDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (
mutation.addedNodes.length === 1 &&
mutation.addedNodes[0].nodeType === Node.TEXT_NODE &&
mutation.removedNodes.length === 1 &&
mutation.removedNodes[0].nodeType === Node.TEXT_NODE
) {
runExtensionFunctions();
}
});
// ANSWERER: Now the observer disconnects itself after the run. Remember: MutationObserver's disconnect itself from *everywhere*
timeInQueueDomObserver.disconnect();
});
//Obervers Configuration
let configChatsContainer = {
childList: true,
};
let configtimeInQueue = {
childList: true,
};
if (goSortDom) {
//boolean is true go ahead run functions and observe
assignChatPriority(incomingChatsRows);
orderIncomingChats();
incomingChatsDomObserver.observe(
incomingChatsContainer[0],
configChatsContainer
);
} else {
//disconnect observers: WON'T WORK
incomingChatsDomObserver.disconnect();
timeInQueueDomObserver.disconnect();
}
}
或者,看看下面的内容。 MutationObserver 绑定到按钮对象,因此单击按钮总是引用一次初始化的 MutationObserver。这样他们就可以断开连接并重新连接(尝试在浏览器中更改 div#changes):
<html>
<body>
<button id="somebutton">bla</button>
<div id="changes"></div>
<script>
document.querySelector("#somebutton").addEventListener("click", function () {
if (!this.incomingChatsDomObserver) {
this.incomingChatsDomObserver = new MutationObserver(function (mutations) {
console.log("incomingChatsDomObserver", mutations);
});
}
if (!this.timeInQueueDomObserver) {
this.timeInQueueDomObserver = new MutationObserver(function (mutations) {
console.log("timeInQueueDomObserver", mutations);
});
}
if (this.observing) {
this.observing = false;
this.incomingChatsDomObserver.disconnect();
this.timeInQueueDomObserver.disconnect();
this.innerText = "inactive";
} else {
this.observing = true;
const changingDiv = document.querySelector("#changes");
this.incomingChatsDomObserver.observe(changingDiv, { attributes: true });
this.timeInQueueDomObserver.observe(changingDiv, { attributes: true });
this.innerText = "active";
}
});
</script>
</body>
</html>
我有一个动态的 DOM 结构,其中节点始终被插入和删除,以便对新节点做出反应我使用的是 MutationObserver,当用户单击 Button 时它会被激活。每次用户单击该按钮时,MutationObserver 都会 运行 两个函数,当我观察到的 DOM 结构发生变化时,这些函数将保持 运行ning。
我想要做的是在用户再次单击按钮时立即断开 MutationObservers(假设第一次单击然后对元素进行排序,再次单击并停止对元素进行排序)。每次用户单击按钮时,我都会传递一个布尔值 (goSortDom)(如果为真,请执行操作并观察,如果为假,则停止观察)。问题是,当我尝试在 goSortDom=false 时断开观察者的连接时,它们永远不会断开连接,并且函数将保持 运行ning.
我对 mutationObservers 很陌生,所以我不知道我的方法是否是一种不好的做法,这就是为什么我也非常感谢对此的评论。
$(document).ready(function () {
// Function 1: Assign Priorities
function assignChatPriority(arrayParent) {
//Assign Priorities
//Observe if time change, if change re-assign priority to dom node
timeInQueueDomObserver.observe(
$(incomingChat).find(".time_cell")[0],
configtimeInQueue
}
// Function 2: Reorder DOM
function orderIncomingChats() {
//Reorder DOM save DOM elements to Array
//Replace original DOM with new sorted DOM
}
//Declaring DOM Observers for Time in Queue and DOM container dynamics
var incomingChatsDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.addedNodes.length) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
if (
mutation.addedNodes[i].attributes["data-priority"] === undefined
) {
runExtensionFunctions();
}
}
}
});
});
var timeInQueueDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (
mutation.addedNodes.length === 1 &&
mutation.addedNodes[0].nodeType === Node.TEXT_NODE &&
mutation.removedNodes.length === 1 &&
mutation.removedNodes[0].nodeType === Node.TEXT_NODE
) {
runExtensionFunctions();
}
});
});
//Obervers Configuration
let configChatsContainer = {
childList: true,
};
let configtimeInQueue = {
childList: true,
};
if (goSortDom) {
//boolean is true go ahead run functions and observe
assignChatPriority(incomingChatsRows);
orderIncomingChats();
incomingChatsDomObserver.observe(
incomingChatsContainer[0],
configChatsContainer
);
} else {
//disconnect observers: WON'T WORK
incomingChatsDomObserver.disconnect();
timeInQueueDomObserver.disconnect();
}
}
您的代码似乎无法识别 (goSortDom) 单击事件。您是否尝试过将该代码字符串添加到您的按钮单击事件中?
Vue.js 框架可能非常适合您的要求。除此之外,我能告诉你的和你知道的一样。当 dom 元素动态改变时,Javascript 行为非常奇怪。我有一个应用程序,该应用程序的选择数量呈指数级增长,这些选择是根据之前的选择加载的。每次加载新信息时,我都必须特别注意用于操作数据的选择器。否则,无论 Id 或 class 选择器如何,JS 都无法使用新导入的数据。我还必须使用 .on( events [ selector ] [ data ] ) Javascript 函数而不是 .click() jquery 函数来完成工作。特别是确保填写了选择器信息。
$("#myDiv").on('click', '.MyDivClass', function(){'Select All and return information'};
您在传递给 .ready() 的函数中初始化并处理 MutationObserver 的 incomingChatsDomObserver
和 timeInQueueDomObserver
。我没有看到外部参考。如果是这种情况,if (goSortDom)
只会对初始化的 MutationObserver 进行一次评估。之后,函数结束,引用丢失。再次调用该函数会创建 new MutationObserver,并且 disconnect() 调用将引用那些新的 MutationObserver,而不是已经观察到的旧 MutationObserver!
难道你想达到的目的是把MutationObserver的初始化和引用移到这个函数外面去用?或者可能会断开 MutationObservers 内部的连接?
让我试一试。由于这不是完整的代码,我无法自己测试它:
- 想法(移动参考):
// ANSWERER: Now the references are outside the ready function. If the ready function is done, this references still exist.
//Declaring DOM Observers for Time in Queue and DOM container dynamics
var incomingChatsDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.addedNodes.length) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
if (
mutation.addedNodes[i].attributes["data-priority"] === undefined
) {
runExtensionFunctions();
}
}
}
});
});
var timeInQueueDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (
mutation.addedNodes.length === 1 &&
mutation.addedNodes[0].nodeType === Node.TEXT_NODE &&
mutation.removedNodes.length === 1 &&
mutation.removedNodes[0].nodeType === Node.TEXT_NODE
) {
runExtensionFunctions();
}
});
});
// ANSWERER: This is now possible
function disconnectObservers() {
incomingChatsDomObserver.disconnect();
timeInQueueDomObserver.disconnect();
}
$(document).ready(function () {
// Function 1: Assign Priorities
function assignChatPriority(arrayParent) {
//Assign Priorities
//Observe if time change, if change re-assign priority to dom node
timeInQueueDomObserver.observe(
$(incomingChat).find(".time_cell")[0],
configtimeInQueue
}
// Function 2: Reorder DOM
function orderIncomingChats() {
//Reorder DOM save DOM elements to Array
//Replace original DOM with new sorted DOM
}
//Obervers Configuration
let configChatsContainer = {
childList: true,
};
let configtimeInQueue = {
childList: true,
};
if (goSortDom) {
//boolean is true go ahead run functions and observe
assignChatPriority(incomingChatsRows);
orderIncomingChats();
incomingChatsDomObserver.observe(
incomingChatsContainer[0],
configChatsContainer
);
} else {
//disconnect observers: WON'T WORK
incomingChatsDomObserver.disconnect();
timeInQueueDomObserver.disconnect();
}
}
- 版本。 MutationObserver 断开连接:
$(document).ready(function () {
// Function 1: Assign Priorities
function assignChatPriority(arrayParent) {
//Assign Priorities
//Observe if time change, if change re-assign priority to dom node
timeInQueueDomObserver.observe(
$(incomingChat).find(".time_cell")[0],
configtimeInQueue
}
// Function 2: Reorder DOM
function orderIncomingChats() {
//Reorder DOM save DOM elements to Array
//Replace original DOM with new sorted DOM
}
//Declaring DOM Observers for Time in Queue and DOM container dynamics
var incomingChatsDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.addedNodes.length) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
if (
mutation.addedNodes[i].attributes["data-priority"] === undefined
) {
runExtensionFunctions();
}
}
}
});
// ANSWERER: Now the observer disconnects itself after the run. Remember: MutationObserver's disconnect itself from *everywhere*
incomingChatsDomObserver.disconnect();
});
var timeInQueueDomObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (
mutation.addedNodes.length === 1 &&
mutation.addedNodes[0].nodeType === Node.TEXT_NODE &&
mutation.removedNodes.length === 1 &&
mutation.removedNodes[0].nodeType === Node.TEXT_NODE
) {
runExtensionFunctions();
}
});
// ANSWERER: Now the observer disconnects itself after the run. Remember: MutationObserver's disconnect itself from *everywhere*
timeInQueueDomObserver.disconnect();
});
//Obervers Configuration
let configChatsContainer = {
childList: true,
};
let configtimeInQueue = {
childList: true,
};
if (goSortDom) {
//boolean is true go ahead run functions and observe
assignChatPriority(incomingChatsRows);
orderIncomingChats();
incomingChatsDomObserver.observe(
incomingChatsContainer[0],
configChatsContainer
);
} else {
//disconnect observers: WON'T WORK
incomingChatsDomObserver.disconnect();
timeInQueueDomObserver.disconnect();
}
}
或者,看看下面的内容。 MutationObserver 绑定到按钮对象,因此单击按钮总是引用一次初始化的 MutationObserver。这样他们就可以断开连接并重新连接(尝试在浏览器中更改 div#changes):
<html>
<body>
<button id="somebutton">bla</button>
<div id="changes"></div>
<script>
document.querySelector("#somebutton").addEventListener("click", function () {
if (!this.incomingChatsDomObserver) {
this.incomingChatsDomObserver = new MutationObserver(function (mutations) {
console.log("incomingChatsDomObserver", mutations);
});
}
if (!this.timeInQueueDomObserver) {
this.timeInQueueDomObserver = new MutationObserver(function (mutations) {
console.log("timeInQueueDomObserver", mutations);
});
}
if (this.observing) {
this.observing = false;
this.incomingChatsDomObserver.disconnect();
this.timeInQueueDomObserver.disconnect();
this.innerText = "inactive";
} else {
this.observing = true;
const changingDiv = document.querySelector("#changes");
this.incomingChatsDomObserver.observe(changingDiv, { attributes: true });
this.timeInQueueDomObserver.observe(changingDiv, { attributes: true });
this.innerText = "active";
}
});
</script>
</body>
</html>