动态子内容上的 MutationObserver
MutationObserver on dynamic child content
我正在处理一个 Prestashop 站点项目,其中包含特别繁琐的 megamenu 设置。
MutationObserver
在打开购物车覆盖层时将菜单推回方面做得很好,但是如果菜单被另一个 JavaScript 库动态拉入,这个问题被混淆了任何救援,因此 MutationObserver
每次都与节点断开链接,如果在页面加载后向购物车添加任何内容,则会导致所有内容绘制不正确。
MutationObserver
当前直接链接到主页容器对象 (category
)。
// CREATE A MUTATION OBSERVER OBJECT TO MONITOR ANY STATE CHANGES ON THE JS NODE
let observer = new MutationObserver(blockCartOpened);
function blockCartOpened(mutationRecords) {
// PROCESS THE LIST OF MUTATION THAT HAVE OCCURED
mutationRecords.forEach (function (mutation) {
// GET THE MUTATION TARGET AND SEE IF THE DISPLAY STYLE ATTRIBUTE IS SET OR NOT
// AND REACT ACCORDINGLY
var target = $(mutation.target);
if(target.hasClass("cart_block")) {
if(target.css("display") == "block") {
$(".ets_mm_megamenu").css("z-index", "-1");
} else {
$(".ets_mm_megamenu").css("z-index", "2");
}
}
mutation.addedNodes.forEach(function(node) {
// Nothing to be here yet...
});
});
}
// SET THE TARGETNODE AS WELL AS THE SETTINGS FOR WHAT TO TRIGGER THE OBSERVER ON, IN THIS CASE
// TRIGGER THE OBSERVER ON ANY CHANGES TO THE STYLE ATTRIBURES OF THE NODE
var targetNodes = document.getElementById("category");
var observerOptions = {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["style"]
}
// SINCE THIS IS A CLASS, A EACH LOOP IS REQUIRED EVEN IF THERE IS ONLY ONE RESULT
observer.observe(targetNodes, observerOptions);
有没有办法监控父节点中创建的子节点的属性变化,或者这只是一个白日梦?
最后我不必使用 MutationObserver,因为事实证明这个问题不适合那种解决方案。所以我选择了阻力最小的路径,即解决方案并不优雅,但效果很好:
// BPK: CODE ADDITIONS
$(document).on("click", function(event) {
var target = $(".blockcart-header");
if(target.hasClass("open")) {
$(".ets_mm_megamenu").css("z-index", "-1");
} else {
$(".ets_mm_megamenu").css("z-index", "2");
}
});
$(document).on("click", ".blockcart-header a", function(event) {
var target = $(".blockcart-header");
if(target.hasClass("open")) {
$(".ets_mm_megamenu").css("z-index", "-1");
} else {
$(".ets_mm_megamenu").css("z-index", "2");
}
});
// END BPK
使用文档范围内的点击事件来监控 "closing" 点击和购物车显示触发按钮上的点击事件,以确保为我解决了这个问题。
教训:不要试图把问题搞得太复杂...
我正在处理一个 Prestashop 站点项目,其中包含特别繁琐的 megamenu 设置。
MutationObserver
在打开购物车覆盖层时将菜单推回方面做得很好,但是如果菜单被另一个 JavaScript 库动态拉入,这个问题被混淆了任何救援,因此 MutationObserver
每次都与节点断开链接,如果在页面加载后向购物车添加任何内容,则会导致所有内容绘制不正确。
MutationObserver
当前直接链接到主页容器对象 (category
)。
// CREATE A MUTATION OBSERVER OBJECT TO MONITOR ANY STATE CHANGES ON THE JS NODE
let observer = new MutationObserver(blockCartOpened);
function blockCartOpened(mutationRecords) {
// PROCESS THE LIST OF MUTATION THAT HAVE OCCURED
mutationRecords.forEach (function (mutation) {
// GET THE MUTATION TARGET AND SEE IF THE DISPLAY STYLE ATTRIBUTE IS SET OR NOT
// AND REACT ACCORDINGLY
var target = $(mutation.target);
if(target.hasClass("cart_block")) {
if(target.css("display") == "block") {
$(".ets_mm_megamenu").css("z-index", "-1");
} else {
$(".ets_mm_megamenu").css("z-index", "2");
}
}
mutation.addedNodes.forEach(function(node) {
// Nothing to be here yet...
});
});
}
// SET THE TARGETNODE AS WELL AS THE SETTINGS FOR WHAT TO TRIGGER THE OBSERVER ON, IN THIS CASE
// TRIGGER THE OBSERVER ON ANY CHANGES TO THE STYLE ATTRIBURES OF THE NODE
var targetNodes = document.getElementById("category");
var observerOptions = {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["style"]
}
// SINCE THIS IS A CLASS, A EACH LOOP IS REQUIRED EVEN IF THERE IS ONLY ONE RESULT
observer.observe(targetNodes, observerOptions);
有没有办法监控父节点中创建的子节点的属性变化,或者这只是一个白日梦?
最后我不必使用 MutationObserver,因为事实证明这个问题不适合那种解决方案。所以我选择了阻力最小的路径,即解决方案并不优雅,但效果很好:
// BPK: CODE ADDITIONS
$(document).on("click", function(event) {
var target = $(".blockcart-header");
if(target.hasClass("open")) {
$(".ets_mm_megamenu").css("z-index", "-1");
} else {
$(".ets_mm_megamenu").css("z-index", "2");
}
});
$(document).on("click", ".blockcart-header a", function(event) {
var target = $(".blockcart-header");
if(target.hasClass("open")) {
$(".ets_mm_megamenu").css("z-index", "-1");
} else {
$(".ets_mm_megamenu").css("z-index", "2");
}
});
// END BPK
使用文档范围内的点击事件来监控 "closing" 点击和购物车显示触发按钮上的点击事件,以确保为我解决了这个问题。
教训:不要试图把问题搞得太复杂...