简体   繁体   中英

JQuery class vs ID

I have a foreach loop here. For every item it prints, there is a comment section that is expandable/collapsable.

The problem I have is, when I hit the "Expand All" for an item, it expands the comments for EVERY item in the loop all at once. Whereas, I only want to see the comments for that specific item.

I know it has something to do with IDs and Classes, but I have zero experience with JQuery. So please help!

<?php
foreach ($items as $item) {

   echo item['comment'];                                
   echo $item['full_name']; ?>

<div id="listContainer">   
            <div class="listControl">
                <a class="expandList">Expand All</a>
                <a class="collapseList">Collapse All</a>
            </div>
            <ul class="expList">
                <li>Item A
                    <ul>
                        <li>Item A.1
                            <ul>
                                <li><span>fidjis</span></li>
                            </ul>
                        </li>
                        <li>Item A.2</li>
                        <li>Item A.3
                            <ul>
                                <li><span>iejowejfiojwiefj.</span></li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li>Item B</li>
                <li>Item C
                    <ul>
                        <li>Item C.1</li>
                        <li>Item C.2
                            <ul>
                                <li><span>sdfkjksdjfnjkdsfnjn</span></li>
                            </ul>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
<?php

        }
        ?>

and here is the Jquery:

function prepareList() {
    $('.expList').find('li:has(ul)')
    .click( function(event) {
        if (this == event.target) {
            $(this).toggleClass('expanded');
            $(this).children('ul').toggle('medium');
        }
        return false;
    })
    .addClass('collapsed')
    .children('ul').hide();

    //Create the button functionality
    $('.expandList')
    .unbind('click')
    .click( function() {
        $('.collapsed').addClass('expanded');
        $('.collapsed').children().show('medium');
    })
    $('.collapseList')
    .unbind('click')
    .click( function() {
        $('.collapsed').removeClass('expanded');
        $('.collapsed').children().hide('medium');
    })

};

You are creating the DIV with ID "listContainer" on every iteration of your loop, this is invalid. An ID should only be used once. Would suggest changing the Id="listContainer" to class="listContainer"

For the jQuery, the problem is that you are referencing all elements with the 'collapsed' class, rather than just the ones that are within the container relating to the Expand All button.

I haven't tested this, but you would want something along these lines

//Create the button functionality
$('.expandList')
.unbind('click')
.click( function() {
    $(this).parents('.listContainer').find('.collapsed').addClass('expanded');
    $(this).parents('.listContainer').find('.collapsed').children().show('medium');
})
$('.collapseList')
.unbind('click')
.click( function() {
    $(this).parents('.listContainer').find('.collapsed').removeClass('expanded');
    $(this).parents('.listContainer').find('.collapsed').children().hide('medium');
})

The difference here is that you start from the button clicked and div with the 'listContainer' class, then work down from there to find all the '.collapsed' elements.

I think you are using classes in place for ID. IDs are used to identify a single elements whereas a class can be applied to more that 1 element. Try to use IDs in your jQuery calls when accessing an individual element. You can try something like:

?>
<div id="listContainer">   
        <div class="listControl">
            <a class="expandList">Expand All</a>
            <a class="collapseList">Collapse All</a>
        </div>
        <ul id="list1" class="expList">
            <li>
                Item A
                <ul>
                    <li>
                        Item A.1
                        <ul>
                            <li>
                                <span>fidjisjfisdjfisdjifjsidfj.</span>
                            </li>
                        </ul>
                    </li>
                    <li>
                        Item A.2
                    </li>
                    <li>
                        Item A.3
                        <ul>
                            <li>
                                <span>iejowejfiojwiefj.</span>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li>
                Item B
            </li>
            <li>
                Item C
                <ul>
                    <li>
                        Item C.1
                    </li>
                    <li>
                        Item C.2
                        <ul>
                            <li>
                                <span> sdfkjksdjfnjkdsfnjn. </span>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
<?php

    }
    ?>

and your jQuery will be something like

function prepareList() {
$('#list1').find('li:has(ul)')
.click( function(event) {
    if (this == event.target) {
        $(this).toggleClass('expanded');
        $(this).children('ul').toggle('medium');
    }
    return false;
})
.addClass('collapsed')
.children('ul').hide();

//Create the button functionality
$('.expandList')
.unbind('click')
.click( function() {
    $('.collapsed').addClass('expanded');
    $('.collapsed').children().show('medium');
})
$('.collapseList')
.unbind('click')
.click( function() {
    $('.collapsed').removeClass('expanded');
    $('.collapsed').children().hide('medium');
})

};

First you should change listContainer into a class attribute.

as ID´s must be unique.

function prepareList() {
    $('.expList').find('li:has(ul)')
        .click( function(event) {
            if (this == event.target) {
                $(this).toggleClass('expanded');
                $(this).children('ul').toggle('medium');
            }
            return false;
        })
        .addClass('collapsed')
        .children('ul').hide();

    //Create the button functionality
    $('.expandList')
        .unbind('click')
        .click( function() {
            // walk up the tree from the clicked button 
            // and find the parent .listContainer
            var $list = $(this).parents(".listContainer");
            // find .collapsed in .listContainer
            $list.find('.collapsed').addClass('expanded');
            $list.find('.collapsed').children().show('medium');
        });

    $('.collapseList')
        .unbind('click')
        .click( function() {
            // walk up the tree from the clicked button 
            // and find the parent .listContainer
            var $list = $(this).parents(".listContainer");
            // find .collapsed in .listContainer
            $list.find('.collapsed').removeClass('expanded');
            $list.find('.collapsed').children().hide('medium');
        });
};

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