简体   繁体   中英

nested li value on click not working

I have elements which have nested li elements and i made a click function to get the value. Every time i click i am getting the same value again and again.

<script type="text/javascript">

    $('.cat-select').on('click',function(){
        $('.cat-list').css('display','block');
         $('.sub-list').css('display','block');

    });

    $(document).on('click','.cat-list>li',function(){
        var selectedVal = $(this).clone()   //clone the element
            .children() //select all the children
            .remove()   //remove all the children
            .end()  //again go back to selected element
            .text();    //get the text of elemen
        console.log(selectedVal);
        $('.cat-select').text(selectedVal);
    });
</script>


<div class="form-group">
   <label for="input-placeholder" class="col-sm-2 control-label"></label>
    <div class="col-sm-10"> 
        <style type="text/css">
            .cat-list, .sub-list{ display: none; }
        </style>
        <div class="cat-group">
            <button class="cat-select" type="button">Select Category</button>
            <ul class="cat-list">
                <li class="have-child">Electronics 
                    <ul class="sub-list">
                        <li class="have-child"> Mobiles & Tablets
                            <ul class="sub-list">
                                <li>Mobiles</li>
                                <li>Tablets</li>
                                <li class="have-child">Accessories</li>
                                    <ul>
                                        <li>Power Bank</li>
                                        <li>Phone Cases</li>
                                    </ul>
                            </ul>
                        </li>
                        <li class="have-child">Cameras
                            <ul class="sub-list">
                                <li>DSLRs</li>
                                <li>Drones</li>
                            </ul>
                        </li>
                    </ul>
                </li>        
            </ul>
        </div>
    </div>
</div>

Every time i click i am getting the same value

https://jsfiddle.net/yx4Ldt80/

The issue you see is because you only attach the event handler to the child of the .cat-list through your use of the > operator.

To solve this, remove that from the selector and call stopPropagation() on the event to stop it bubbling up the DOM. Try this:

$(document).on('click', '.cat-list li', function(e) {
    e.stopPropagation();
    var selectedVal = $(this).clone().children().remove().end().text();
    $('.cat-select').text(selectedVal);
})

 $('.cat-select').on('click', function() { $('.cat-list, .sub-list').toggle(); }); $(document).on('click', '.cat-list li', function(e) { e.stopPropagation(); var selectedVal = $(this).clone().children().remove().end().text(); $('.cat-select').text(selectedVal); })
 .cat-list, .sub-list { display: none; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> <div class="form-group"> <label for="input-placeholder" class="col-sm-2 control-label"></label> <div class="col-sm-10"> <div class="cat-group"> <button class="cat-select" type="button">Select Category</button> <ul class="cat-list"> <li class="have-child">Electronics <ul class="sub-list"> <li class="have-child"> Mobiles &amp; Tablets <ul class="sub-list"> <li>Mobiles</li> <li>Tablets</li> <li class="have-child">Accessories <ul> <li>Power Bank</li> <li>Phone Cases</li> </ul> </li> </ul> </li> <li class="have-child"> Cameras <ul class="sub-list"> <li>DSLRs</li> <li>Drones</li> </ul> </li> </ul> </li> </ul> </div> </div> </div>

Also note that I fixed the HTML in your 'Accessories' ul as it was outside of the parent li .

" Never use " Event.stopPropagation()

The worst thing you can do (as suggested by answers here and around the web) is to use Event.stopPropagation() .
Don't use Event.stopPropagation() , well, unless you really know what you're doing .

An Application should be always aware of every event happening in it's context.
Imagine you build a popup, modal, or a custom select-box that needs to close if you click anywhere else in the page. Well, congratulations, a LI element just stopped you from doing so.

Use Event.target instead

function myClickHandler(ev) {
  if (ev.target !== this) return; // Ignore if non-this called the event
  console.log( this.textContent );
}

Here's an example with your specific use-case:

 const $cat = $('.cat-select'); $cat.on('click', function() { $('.cat-list, .sub-list').toggle(); }); $(document).on('click', '.cat-list li', function(ev) { if (ev.target !== this) return; // Ignore if non-this called the event const value = $(this).contents().filter((i, el) => el.nodeType == 3)[0].nodeValue; $cat.text(value); }); // Than, 3000 lines later... THANK YOU BECAUSE: $('body').on('click', function() { // Close a popup or something console.clear(); console.log(`YEY I registered an event! Thank you for not using Event.preventDefault()`); });
 .cat-list, .sub-list { display: none; }
 <div class="form-group"> <label for="input-placeholder" class="col-sm-2 control-label"></label> <div class="col-sm-10"> <div class="cat-group"> <button class="cat-select" type="button">Select Category</button> <ul class="cat-list"> <li class="have-child">Electronics <ul class="sub-list"> <li class="have-child"> Mobiles & Tablets <ul class="sub-list"> <li>Mobiles</li> <li>Tablets</li> <li class="have-child">Accessories</li> <ul> <li>Power Bank</li> <li>Phone Cases</li> </ul> </ul> </li> <li class="have-child">Cameras <ul class="sub-list"> <li>DSLRs</li> <li>Drones</li> </ul> </li> </ul> </li> </ul> </div> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Get the clicked element based the event.target property. Although you can avoid the clone by contents() and filter() methods which help to filter out text nodes.

$(document).on('click', 'li', function(e) {
  // if target element is not `li` tag then get closest li tag
  var selectedVal = (e.target.nodeType == 'LI' ? $(e.target) : $(e.target).closest('li'))
    .contents() // get all children nodes 
    .filter(function() { // filter  out text nodes
      return this.nodeType === 3;
    }).text(); // get text content

  $('.cat-select').text(selectedVal);
})

 $(document).on('click', 'li', function(e) { // if target element is not `li` tag then get closest li tag var selectedVal = (e.target.nodeType == 'LI' ? $(e.target) : $(e.target).closest('li')) .contents() // get all children nodes .filter(function() { // filter out text nodes return this.nodeType === 3; }).text(); // get text content $('.cat-select').text(selectedVal); })
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="form-group"> <label for="input-placeholder" class="col-sm-2 control-label"></label> <div class="col-sm-10"> <div class="cat-group"> <button class="cat-select" type="button"> Select Category</button> <ul class="cat-list"> <li class="have-child">Electronics <ul class="sub-list"> <li class="have-child">Mobiles & Tablets <ul class="sub-list"> <li>Mobiles</li> <li>Tablets</li> <li class="have-child">Accessories</li> <ul> <li>Power Bank</li> <li>Phone Cases</li> </ul> </ul> </li> <li class="have-child">Cameras <ul class="sub-list"> <li>DSLRs</li> <li>Drones</li> </ul> </li> </ul> </li> </ul> </div> </div>

i hope this one is helping u

$('.cat-select').each(function() {
    $(this).on('click', function() {
    $('.cat-list').css('display', 'block');
    $('.sub-list').css('display', 'block');
    });
});
$(document).on('click', function() {
    $(this).each('.cat-list li', function() {
      var selectedVal = $(this).clone() //clone the element
        .children() //select all the children
        .remove() //remove all the children
        .end() //again go back to selected element
        .text(); //get the text of elemen
        console.log(selectedVal);
        $('.cat-select').text(selectedVal);
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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