我在为 OffcanvasMenu 列表添加单击事件时遇到问题。我需要为每个 li 元素添加此事件。我正在使用 Shopware 6。 但是当我尝试使用 jQuery 添加 li 元素的单击事件时,没有任何反应。 我扩展了 OffcanvasMenu。这是我的代码:
import OffcanvasMenuPlugin from 'src/plugin/main-menu/offcanvas-menu.plugin.js';
export default class ExtendOffcanvasMenuPlugin extends OffcanvasMenuPlugin {
init() {
super.init();
this._registerEvents();
console.log("inner");
}
_registerEvents() {
super._registerEvents();
let list = document.querySelector('.navigation-offcanvas-list-item');
console.log(list);
list.addEventListener('click', (e) => {
console.log("inner event");
e.preventDefault();
});
}
}
在 main.js 文件中我重写了这个插件:
PluginManager.override('OffcanvasMenu', ExtendOffcanvasMenuPlugin, '[data-offcanvas-menu]');
是否有可能在 OffcanvasMenu 插件中的每个 li 元素上添加事件?
普遍的问题似乎是当前代码使用
querySelector
来收集所有元素。然而,querySelector
只产生与选择器匹配的第一个元素,即使有多个,请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
您可以通过使用 querySelectorAll 来解决这个问题,它的作用基本上相同,但返回所有找到的元素的可迭代列表。然后您可以迭代列表并将侦听器附加到每个元素:
import OffcanvasMenuPlugin from 'src/plugin/main-menu/offcanvas-menu.plugin.js';
export default class ExtendOffcanvasMenuPlugin extends OffcanvasMenuPlugin {
_registerEvents() {
super._registerEvents();
let list = document.querySelectorAll('.navigation-offcanvas-list-item');
console.log(list);
list.forEach((listItem) => {
listItem.addEventListener('click', (e) => {
console.log("inner event");
e.preventDefault();
});
});
}
}
这在理论上是可行的,但实际上,
a.navigation-offcanvas-link
位于您想要附加监听器的<li>
内部。 a.navigation-offcanvas-link
元素已经有一个事件侦听器 (_getLinkEventHandler
),并且还占据了 <li>
内的所有空间,这就是为什么 <li>
本身实际上不可点击。
解决方法可能是首先从
a.navigation-offcanvas-link
中删除监听器并使其不可点击,但这取决于您想要实现的目标。每次单击菜单项时是否都应该执行一些额外的操作?然后你可以考虑直接扩展方法_getLinkEventHandler
,即使它被标记为私有并且可能在未来版本中发生变化。
我在使用 offcanvas-cart 时遇到了同样的问题。由于 offcanvas 内容是通过 AJAX 调用插入的,因此 js 将不会触发。我用一个mutationObserver来监听任何新节点解决了这个问题。这在第一次尝试中有效,但您必须等待内容可用,这就是为什么我将实际代码包装到 setTimeout 函数中。问题是:带宽较低的用户可能需要更长的时间来加载页面,并且很难确定应该设置多长时间的超时。否则,并非每个访问者都可以使用该内容。因此,您最好尝试使用修改后的树枝模板来解决您的问题。这就是我暂时解决这个问题的方法:
document.addEventListener('DOMContentLoaded', function() {
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes.length > 0) {
mutation.addedNodes.forEach(function(node) {
if (node.classList && node.classList.contains('cart-offcanvas')) {
// Add delay to make shure content is available
setTimeout(function() {
// Your code goes here..
}, 2000);
console.log('Offcanvas loaded in DOM.');
}
});
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
});