this.element的closest()无法正常工作



我有一个这样的HTML。:当我点击标记<a>时,我需要使用选择器".container"获得最近的父节点脚本如下,但它只适用于第一列(第一列指定选择器(如何使代码像使用this参数或其他东西一样正常工作?

<div class="wrapper">
<div class="container">
<div class="sub-container">
<ul>
<li><a href="#" data-color="red" class="red"></a></li>
<li><a href="#" data-color="green" class="green"></a></li>
<li><a href="#" data-color="blue" class="blue"></a></li>
</ul>
</div>
</div>
<div class="container">
<div class="sub-container">
<ul>
<li><a href="#" data-color="red" class="red"></a></li>
<li><a href="#" data-color="green" class="green"></a></li>
<li><a href="#" data-color="blue" class="blue"></a></li>
</ul>
</div>
</div>
<div class="container">
<div class="sub-container">
<ul>
<li><a href="#" data-color="red" class="red"></a></li>
<li><a href="#" data-color="green" class="green"></a></li>
<li><a href="#" data-color="blue" class="blue"></a></li>
</ul>
</div>
</div>
</div>

这是的脚本

<script>    
(() =>{
const a = document.querySelectorAll('a');
for(let i=0; i<a.length; i++){
a[i].setAttribute('onclick', `handleClick('${a[i].getAttribute('data-color')}', '${a[i].nodeName}')`);
}
handleClick = (color, selector) => {
document.querySelector(selector).closest('.container').style.backgroundColor = color;
}
})()
</script>

您应该使用.addEventListener()添加事件处理程序,并且处理程序应该是函数,而不是字符串:

(() => {
const a = document.querySelectorAll("a");
for (let i = 0; i < a.length; ++i) {
a[i].addEventListener("click", function() {
this.closest(".container").style.backgroundColor = this.getAttribute("data-color");
});
}
})();

您也可以使用委托设置来完成此操作,这样您就可以在文档级别处理"点击",并在事件目标与".container a"匹配时(或任何有效的方法(将其发送到颜色转换器。

通过将颜色传递给事件处理程序,使其过于复杂。您正在使用一个数据属性,所以只需在单击元素时读取它。

(() => {

const handleClick = evt => {
// stop the click
evt.preventDefault()
// get the color
const color = evt.target.dataset.color
// reference the container element
const wrapper = evt.target.closest('.container')
// clean up classes
wrapper.classList.remove('red', 'green', 'blue')
//set class for what was clicked
wrapper.classList.add(color)
}

const anchors = document.querySelectorAll('a');
anchors.forEach(a => a.addEventListener('click', handleClick))
})()
a:after {
content: attr(data-color)
}
div.red {
background-color: red
}
div.green {
background-color: green
}
div.blue {
background-color: blue
}
<div class="wrapper">
<div class="container">
<div class="sub-container">
<ul>
<li>
<a href="#" data-color="red" class="red"></a>
</li>
<li>
<a href="#" data-color="green" class="green"></a>
</li>
<li>
<a href="#" data-color="blue" class="blue"></a>
</li>
</ul>
</div>
</div>
<div class="container">
<div class="sub-container">
<ul>
<li>
<a href="#" data-color="red" class="red"></a>
</li>
<li>
<a href="#" data-color="green" class="green"></a>
</li>
<li>
<a href="#" data-color="blue" class="blue"></a>
</li>
</ul>
</div>
</div>
<div class="container">
<div class="sub-container">
<ul>
<li>
<a href="#" data-color="red" class="red"></a>
</li>
<li>
<a href="#" data-color="green" class="green"></a>
</li>
<li>
<a href="#" data-color="blue" class="blue"></a>
</li>
</ul>
</div>
</div>
</div>

现在,您甚至可以避免锚点上的循环,并使用事件委派

(() => {

const handleClick = evt => {
// look to see if what we click has the data attribute
const color = evt.target.dataset.color
// if we do not have the color, than just ignore the click
if(!color) return
// stop the click
evt.preventDefault()
// reference the container element
const container = evt.target.closest('.container')
// clean up classes
container.classList.remove('red', 'green', 'blue')
//set class for what was clicked
container.classList.add(color)
}

const wrapper = document.querySelector('.wrapper')
wrapper.addEventListener('click', handleClick)
})()
a:after {
content: attr(data-color)
}
div.red {
background-color: red
}
div.green {
background-color: green
}
div.blue {
background-color: blue
}
<div class="wrapper">
<div class="container">
<div class="sub-container">
<ul>
<li>
<a href="#" data-color="red" class="red"></a>
</li>
<li>
<a href="#" data-color="green" class="green"></a>
</li>
<li>
<a href="#" data-color="blue" class="blue"></a>
</li>
</ul>
</div>
</div>
<div class="container">
<div class="sub-container">
<ul>
<li>
<a href="#" data-color="red" class="red"></a>
</li>
<li>
<a href="#" data-color="green" class="green"></a>
</li>
<li>
<a href="#" data-color="blue" class="blue"></a>
</li>
</ul>
</div>
</div>
<div class="container">
<div class="sub-container">
<ul>
<li>
<a href="#" data-color="red" class="red"></a>
</li>
<li>
<a href="#" data-color="green" class="green"></a>
</li>
<li>
<a href="#" data-color="blue" class="blue"></a>
</li>
</ul>
</div>
</div>
</div>

最新更新