简体   繁体   English

this.element的最近()不能正常工作

[英]closest() of this.element not works properly

I have an HTML like this.: And when I click on tag <a> I need to get closest parent node with selector ".container" The script is below, but it works only for the first one column (with the first one specify selector) How to bring the code works properly like with this parameter or something else? 我有一个这样的HTML ".container"当我单击标记<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>

Here is the script 这是脚本

<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>

You should add event handlers with .addEventListener() , and the handlers should be functions, not strings: 您应该使用.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");
    });
  }
})();

You could also do it with a delegation setup, such that you handle "clicks" at the document level and dispatch to the color changer when the event target matches ".container a" (or whatever works). 您也可以使用委派设置来执行此操作,以便在事件目标与".container a" (或其他有效方法)匹配时,在文档级别处理“单击”并分派给换色器。

You are over complicating it by passing in colors to the event handler. 通过将颜色传递给事件处理程序,您使它过于复杂。 You are using a data attribute so just read it when you click on the element. 您正在使用数据属性,因此单击元素时只需读取它即可。

 (() => { 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> 

Now you can even avoid the loop over the anchors and use event delegation 现在,您甚至可以避免在锚点上循环,并使用事件委托

 (() => { 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM