简体   繁体   中英

jquery .prev() strange behavior

I have a very simple list of LI's and they are all on the same level (nothing nested) I want to find the previous element of any element who's class is level1. For some reason prev() is failing on items when the 'level1' element is more than one sibling away. I don't want to use prevAll() because I only want the closest li that comes before my element and has a class of level1.

<ul id="main-list">
    <li class="level1" data-id="1" data-parent="none" id="recordsArray_1">Overview</li>
    <li class="level2" data-id="4" data-parent="Overview" id="recordsArray_4">Benefits</li>
    <li class="level2" data-id="2" data-parent="undefined" id="recordsArray_2">Core Concepts</li>
    <li class="level2" data-id="3" data-parent="undefined" id="recordsArray_3">Access</li>
    <li class="level3" data-id="5" data-parent="Access" id="recordsArray_5">Onboarding</li>
    <li class="level1" data-id="12" data-parent="none" id="recordsArray_12">test top</li>
    <li class="level2" data-id="10" data-parent="test top" id="recordsArray_10">test 1</li>
    <li class="level2" data-id="14" data-parent="undefined" id="recordsArray_14">New Access</li>
    <li class="level3" data-id="13" data-parent="New Access" id="recordsArray_13">test 2</li>
    <li class="level1" data-id="6" data-parent="none" id="recordsArray_6">Underview</li>
    <li class="level2" data-id="7" data-parent="Underview" id="recordsArray_7">coolpage1</li>
    <li class="level3" data-id="9" data-parent="coolpage1" id="recordsArray_9">page level 3</li>
</ul>

<script>
var publishList = $('#main-list li');

$.each(publishList, function () {
    var thisClass = $(this).attr('class');
    var parentID = $(this).attr('data-parent');
    var recordID = $(this).attr('data-id');

    if (thisClass == 'level2') {
        var thisParent = $(this).prev('.level1').html();
        console.log(this);    
    }
}); 
</script>

console output:

Overview
undefined
undefined
test top
undefined
Underview

What am I doing wrong? I expected prev() to return overview for core concepts, access and New Access but they are coming back undefined. Is there a flaw in my logic?

Try a combination of .prevAll() and .first()

var thisParent = $(this).prevAll('.level1').first().html();

This will make sure you always get the closest possible sibling no matter the distance.

Try this code

var publishList = $('#main-list li');

$.each(publishList, function () {
    var $this = $(this),
        thisClass = $this.attr('class'),
        parentID = $this.attr('data-parent'),
        recordID = $this.attr('data-id');

    if (thisClass == 'level2') {
        var thisParent = $this.prevAll('.level1').first().html();
        $('#output').append($this.prevAll('.level1').first().html()+'<br />');
    }

});

Check Fiddle

.prev() doesn't provide the functionality you want. The functionality you're looking for is in .prevAll()

Once you have a set of values from .prevAll() you can use something like .first() to get what you need (as has been mentioned) or identify the closest element by id (ie .split() a number-based id or some similar method). However you decide to go about it, .prev() won't get you what you want.

只需更新您的if语句

    if (thisClass == 'level2' && $(this).prev('.level1').length) {

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