纯JS的新功能。
我正在创建必须与移动设备配合使用的菜单。
我正在尝试使用纯.js而不是使用jQuery进行创建,这是一个实验,并且充满挑战。
这是我的代码:
JS:
(function() {
var menu = document.querySelector('.mobile-menu');
var subMenu = {
downToggle: document.getElementsByClassName('sub-menu'),
downToggleTitle: document.getElementsByClassName('sub-menu-title'),
subMenuItems: document.getElementsByClassName('sub-menu-item-mobile'),
searchBar: document.getElementById('mobile-search'),
onclickimg: document.querySelectorAll('.sub-menu-arrow'),
};
function listen() {
for(var i=0; i<subMenu.downToggleTitle.length; i++) {
subMenu.downToggleTitle.item(i).addEventListener('click', function(e) {
// if there is a menu that's already open and it's not the element that's been clicked, close it before opening the selected menu
for(var i=0; i<subMenu.downToggleTitle.length; i++) {
if (subMenu.downToggleTitle.item(i).classList.contains('expanded') && subMenu.downToggleTitle.item(i) !== e.target) {
subMenu.downToggleTitle.item(i).classList.toggle('expanded');
}
}
// inside each sub-menu is a third-level-sub-menu. So inside each sub-menu we
// check if it's already open, then close it
for(var i=0; i<subMenu.subMenuItems.length; i++) {
// console.log("test test")
if(subMenu.subMenuItems.item(i).classList.contains('expanded') && subMenu.subMenuItems.item(i) !== e.target) {
subMenu.subMenuItems.item(i).classList.toggle('expanded');
}
}
this.classList.toggle('expanded');
});
}
for(var i=0; i<subMenu.subMenuItems.length; i++) {
subMenu.subMenuItems.item(i).addEventListener('click', function(e) {
for(var i=0; i<subMenu.subMenuItems.length; i++) {
if(subMenu.subMenuItems[i].classList.contains('expanded') && subMenu.subMenuItems[i] !== e.target) {
subMenu.subMenuItems[i].classList.toggle('expanded');
console.log("hello Aug 20");
}
}
this.classList.toggle('expanded');
});
}
} listen();
}());
我要更改的行为如下:
在第一个版本中,如果客户按下.sub-menu-title
类的downToggleTitle
类(变量li
),则元素将切换类{{1} }。现在我想要一些不同的东西。
我在列表元素的末尾添加了expanded
类,即变量sub-menu-arrow
到onclickimg
上,所以如果客户单击箭头,所有类元素img
(sub-menu-title
)将切换类var = downToggleTitle
。
不会发生这种情况,因为如果出于某种原因,我以这种方式更改代码:
expanded
类subMenu.onclickimg.item(i).addEventListener('click', function(e) {
for(var i=0; i<subMenu.downToggleTitle.length; i++) {
if (subMenu.downToggleTitle.item(i).classList.contains('expanded') && subMenu.downToggleTitle.item(i) !== e.target) {
subMenu.downToggleTitle.item(i).classList.toggle('expanded');
}
}
将切换到expanded
元素(就像我说的,一些带有动画的图像)。
在这种情况下,关于如何定位父元素的任何建议?
还可以从点击事件中排除类别为sub-menu-arrow
的锚元素吗?
mobile-toplevel-link
元素是<a>
类的其他子元素
答案 0 :(得分:0)
如果要获取被单击目标的父元素,则可以利用当前的eventListener
并使用e.target.parentNode
来获取它。这将返回一个元素,您可以从中添加/删除CSS类,并可以完成几乎所有您喜欢的事情。请记住,您可以多次使用.parentNode
,例如,如果要获取某个元素的“祖父母”(2级以上),可以编写e.target.parentNode.parentNode
,依此类推。>
答案 1 :(得分:0)
这实际上只是一条评论。您可以使用现代NodeList的迭代器功能极大地简化代码。我看不到 subMenu 对象的意义,它只是使引用更长。
此外,我替换了 getElementsByClassName ,因为它会生成一个活动的NodeList,而 querySelectorAll 返回一个静态列表。这里差别不大,但在其他情况下可能会很重要。
以下是一个简单的重构,它应该与您当前的代码应该完全一样。请注意,对于箭头功能, this 是从封闭的执行上下文中采用的。
(function() {
let menu = document.querySelector('.mobile-menu');
let downToggle = document.querySelectorAll('.sub-menu'),
downToggleTitle = document.querySelectorAll('.sub-menu-title'),
subMenuItems = document.querySelectorAll('.sub-menu-item-mobile'),
searchBar = document.getElementById('mobile-search'),
onclickimg = document.querySelectorAll('.sub-menu-arrow');
function listen() {
downToggleTitle.forEach(dtTitle => {
dtTitle.addEventListener('click', function(e) {
// If there is a menu that's already open
// and it's not the element that's been clicked,
// close it before opening the selected menu
downToggleTitle.forEach(node => {
if (node.classList.contains('expanded') && node !== this) {
node.classList.toggle('expanded');
}
});
// inside each sub-menu is a third-level-sub-menu. So inside each sub-menu
// If it's already open, close it
subMenuItems.forEach(item => {
// console.log("test test")
if (item.classList.contains('expanded') && item !== this) {
item.classList.toggle('expanded');
}
});
this.classList.toggle('expanded');
});
});
subMenuItems.forEach(item => {
item.addEventListener('click', function(e) {
subMenuItems.forEach(item => {
if (items.classList.contains('expanded') && item !== this) {
item.classList.toggle('expanded');
console.log("hello Aug 20");
}
});
this.classList.toggle('expanded');
});
});
}
listen();
}());