0

In the following code snippet, I want to capture the outermost element(li .menu-item) when the button is clicked.

Normally, I could use document.querySelector(.menu-item), but in this case, these list items are dynamically added so multiple li elements exist with the menu-item class.

How do I get the closest li ancestor in order to extract the values of its children

<li class="menu-item">
    <div class="item">
        <p>Chicken Veg Roll</p>
        <img src="../../assets/img/menu/tasty-rolls.jpg">
    </div>
    <p class="price">1350.00</p>
    <button class="order-btn" form="menu-item-form" type="submit">Add to Order</button>
</li>
Mario
  • 4,784
  • 3
  • 34
  • 50
Oguntoye
  • 645
  • 1
  • 7
  • 19
  • 3
    Possible duplicate of [Getting the parent div of element](https://stackoverflow.com/questions/6856871/getting-the-parent-div-of-element) – Robby Cornelissen Sep 27 '18 at 04:21
  • The awesome [jquery libray](https://jquery.com/) makes traversing the DOM trivial. The [closest](https://api.jquery.com/closest/) or [parents](https://api.jquery.com/parents/) methods could help you out here. **Don't** use jquery *just* for this, but evaluate if its features are worth the library overhead to your website. – Jon P Sep 27 '18 at 04:44

3 Answers3

1

I make some assumptions about your case, but you can use closest

From MDN

The Element.closest() method returns the closest ancestor of the current element (or the current element itself) which matches the selectors given in parameter. If there isn't such an ancestor, it returns null.

Take a look to this example

const buttons = document.querySelectorAll('.order-btn');

buttons.forEach(button => button.addEventListener('click', handleClick));

function handleClick(e) {
    e.preventDefault();

    const li = this.closest('li');

    li.style.background = 'red';
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <ul>
        <li class="menu-item">
            <div class="item">
                <p>Chicken Veg Roll</p>
                <img src="../../assets/img/menu/tasty-rolls.jpg">
            </div>
            <p class="price">1350.00</p>
            <button class="order-btn" form="menu-item-form" type="submit">Add to Order</button>
        </li>
        <li class="menu-item">
            <div class="item">
                <p>Chicken Veg Roll</p>
                <img src="../../assets/img/menu/tasty-rolls.jpg">
            </div>
            <p class="price">1350.00</p>
            <button class="order-btn" form="menu-item-form" type="submit">Add to Order</button>
        </li>
        <li class="menu-item">
            <div class="item">
                <p>Chicken Veg Roll</p>
                <img src="../../assets/img/menu/tasty-rolls.jpg">
            </div>
            <p class="price">1350.00</p>
            <button class="order-btn" form="menu-item-form" type="submit">Add to Order</button>
        </li>
        <li class="menu-item">
            <div class="item">
                <p>Chicken Veg Roll</p>
                <img src="../../assets/img/menu/tasty-rolls.jpg">
            </div>
            <p class="price">1350.00</p>
            <button class="order-btn" form="menu-item-form" type="submit">Add to Order</button>
        </li>
        <li class="menu-item">
            <div class="item">
                <p>Chicken Veg Roll</p>
                <img src="../../assets/img/menu/tasty-rolls.jpg">
            </div>
            <p class="price">1350.00</p>
            <button class="order-btn" form="menu-item-form" type="submit">Add to Order</button>
        </li>
    </ul>
</body>
</html>

If the li elements are added dynamically you should probably implement Event delegation

Mario
  • 4,784
  • 3
  • 34
  • 50
  • Just note that `closest` won't work in IE without a polyfill. – Jon P Sep 27 '18 at 06:59
  • Jon P is right about IE, the polyfill is here https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill – Mario Sep 27 '18 at 14:20
0

function clickHandler(event) {
  alert(event.target.parentNode.tagName);
}
<li> Test<br>
<button onclick="clickHandler(event)">Click me</button>
</li>
Saikrishna Rajaraman
  • 3,205
  • 2
  • 16
  • 29
0
<li class="menu-item">
    <div class="item">
        <p>Chicken Veg Roll</p>
        <img src="../../assets/img/menu/tasty-rolls.jpg">
    </div>
    <p class="price">1350.00</p>
    <button class="order-btn" form="menu-item-form" type="submit">Add to Order</button>
</li>   



 document.querySelector(".order-btn").addEventListener("click",function(e){
    console.log(e.target.parentElement);
 });
Chayan
  • 604
  • 5
  • 12