why js closest method not find sibling element?
Asked Answered
W

2

6

Note: as far as i know that closest() method searches up the DOM tree for the closest element which matches a specified CSS selector.

When i click on margin space between two li element .. it's return null... but if i replace margin-bottom: 15px; with padding-bottom... everything is okay...

CSS Code

.amenities-filters-inner ul li{
    margin-bottom: 15px;
}

Image if i click on red mark area.. it's not found sibling li element ..

enter image description here

Example Code

   document.querySelectorAll(".amenities-filters-inner ").forEach(function(item){
    item.addEventListener("click",function(e){
        e.preventDefault();

        let element = null;
        element = e.target.closest(".amenity_id");
        // element = e.target.querySelector(".amenity_id");
         element = element.children[0].children[1];
         element.checked == true ? element.checked = false :  element.checked =true;
       
        let dataId =  + element.getAttribute('data-id');
        console.log(element)
        console.log(dataId)
       
    })
})
 .amenities-filters-inner{
        
            border: 2px dashed royalblue;
            max-width: 300px;
            padding: 1rem;
        }
        ul{
            list-style: none;
            width: 100%;
            margin: 0;
            padding: 0;
           
        }
        li{
            border: 2px solid rgb(133, 129, 129);
            padding: 3px;
        }


.amenities-filters-inner:last-child{
    margin-bottom: 0;
}

.amenities-filters-inner ul li{
    margin-bottom: 20px;
}
.amenities-filters-inner ul li:last-child{
    margin-bottom: 0;
}

.check {
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: relative;
    padding-left: 31px;
    margin-bottom: 0;
    padding-right: 0;
    cursor: pointer;
    font-size: 14px; 
    color: #646464;
}
.check  strong{
    color: #969696;
    font-size: 14px; 
    font-weight: 400;
}

.check input {
    position: absolute;
    opacity: 0;
    cursor: pointer;
}


.checkmark {
    position: absolute;
    top: 0;
    left: 0;
    height: 17px;
    width: 17px;
    background-color: #fff ;
    border-color: #646464;
    border-style:solid;
    border-width:1px;
    border-radius: 2px;
}

.check input:checked ~ .checkmark {
    background-color: #fff;
    border-color: #007FEB;
}
.checkmark:after {
    content: "";
    position: absolute;
    display: none;
}
.check input:checked ~ .checkmark:after {
    display: block;
}
.check .checkmark:after {
    left: 5px;
    top: 1px;
    width: 5px;
    height: 10px;
    border: solid ;
    border-color:#007FEB;
    border-width: 0 2px 2px 0;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
}
   <div class="amenities-filters-inner">
            <ul>
                <li class="amenity_id">
                    <label class="check ">One <strong>One</strong>
                        <input type="checkbox" class="amenity_data" data-id="1" name="is_name">
                        <span class="checkmark"></span>
                    </label>
                </li>
                <li class="amenity_id">
                    <label class="check ">Two <strong>Two</strong>
                        <input type="checkbox" class="amenity_data" data-id="2"name="is_name">
                        <span class="checkmark"></span>
                    </label>
                </li>
<li class="amenity_id">
                    <label class="check ">Three<strong>Three</strong>
                        <input type="checkbox" class="amenity_data" data-id="3"name="is_name">
                        <span class="checkmark"></span>
                    </label>
                </li>
              
               
            </ul>
        </div>
Wilinski answered 7/12, 2020 at 12:35 Comment(5)
If you click inside the margin, the event target is the <ul>, from where no closest element that matches .amenity_id is available.Hyacinth
@Hyacinth better you can put as an answer ...Galvanometer
I'm not quite sure how to answer, because I can't see what your intention is actually.Hyacinth
@Hyacinth you find out the actual problem ... it's your credit....i try to delete this question... it's giving me alert you can not delete ...Galvanometer
Personally I think both given answers are correct in their statements, so a third answer feels unnecessary (imho).Hyacinth
W
4

.closest() method only traverses parents, not children.

That area is in container .amenities-filters-inner not inside list element, so it won't find the .amenities-id.

Change the background color of container to debug.

.amenities-filters-inner{
  background: red;
}

If you don't want gaps between list items, don't use margin. Use padding-top and padding-bottom instead.

The closest() method traverses the Element and its parents (heading toward the document root) until it finds a node that matches the provided selector string. Will return itself or the matching ancestor. If no such element exists, it returns null.

https://developer.mozilla.org/en-US/docs/Web/API/Element/closest

Wares answered 7/12, 2020 at 12:51 Comment(0)
C
2

By clicking inside the red marked area, you are clicking between the two <li> elements which means you are inside the <ul> element. Calling closest() on target brings you up to <div>; what you are looking for is a child inside (that is, down) the <ul> element. Try changing

element = e.target.closest(".amenity_id");

in your script to

element = e.target.querySelector(".amenity_id");

and see if it works.

Classic answered 7/12, 2020 at 19:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.