jQuery: вставьте тег <li>в список по порядку - PullRequest
5 голосов
/ 09 декабря 2011

у меня порядка <li> меток:

var order = ["a-link", "b-link", "c-link", "d-link", "e-link", "f-link"];

Некоторые из тегов <li> могут быть или не быть в списке в любой момент:

т.е.

<ul>
<li id="a-link"></li>
<li id="d-link"></li>
</ul>

Я хотел бы сказать, вставьте тег <li> в правильном порядке ...

    <ul>
        <li id="a-link"></li> 
<!-- i'd like to insert <li id="b-link"> right after this -->
        <li id="d-link"></li>
    </ul>

Иногда мой список может выглядеть так:

    <ul>
    <li id="b-link"></li>

<!-- but maybe I want to insert a <li id="d-link"> here-->

    <li id="e-link"></li>
    </ul>

Или вот так:

    <ul>
    <li id="a-link"></li>
    <li id="d-link"></li>
<!-- but maybe I want to insert a <li id="e-link"> here-->
    <li id="f-link"></li>
    </ul>

По сути, список может измениться ... но всякий раз, когда я хочу вставить тег <li> (по одному за раз), он должен располагаться в правильном порядке в качестве массива заказов.

Ответы [ 2 ]

2 голосов
/ 09 декабря 2011

Мое понимание вопроса, похоже, отличается от других ответов (это слово?).

Мое понимание вопроса заключается в том, что вы хотите вставить один элемент на страницу, где уже существует неизвестное число других элементов. Вы хотите, чтобы этот единственный элемент был вставлен в список в порядке, определенном вашим массивом.


РЕДАКТИРОВАТЬ: Другой вариант, который может иметь лучшую производительность, - это найти индекс в массиве порядка элемента, который вы хотите вставить. Затем цикл от этого индекса до конца. Как только вы найдете элемент, который существует, вставьте новый элемент перед ним.

http://jsfiddle.net/bWPX8/5/

var order = ["a-link", "b-link", "c-link", "d-link", "e-link", "f-link"];        

var toInsert = "c-link";
var insertIndex = order.indexOf(toInsert);

if($("ul>li").length === 0){

    $("ul").append(  $("<li>",{id:toInsert}));

}else if($("#"+toInsert).length===0){
    var inserted = false;

    for(var i = insertIndex + 1, len = order.length; i<len; i++){
        var $el = $("#" + order[i]);

        if($el.length > 0){
            $el.before($("<li>",{id:toInsert}));
            inserted = true;
            break;
        }
    }

    if(!inserted){
         // should be last
          $("ul").append($("<li>",{id:toInsert}));
    }
}

Для еще большей производительности, определите, находится ли индекс вашего элемента до или после средней точки массива, а также цикл вперед или назад в зависимости от того, что будет меньше итераций цикла.


Если это вопрос, вот грубый способ сделать это. Если список значительно больше приведенного примера, производительность может быть невелика.

http://jsfiddle.net/bWPX8/3/

Array.indexOf может не поддерживаться какой-либо версией IE, поэтому его, возможно, придется заменить чем-то другим.

0 голосов
/ 09 декабря 2011

Чтобы добавить решение для обновленной информации, о которой идет речь:

var ul = document.getElementsByTagName('ul')[0],
    lis = ul.getElementsByTagName('li'),
    order = ["a-link", "b-link", "c-link", "d-link", "e-link", "f-link"],
    toInsert = "b-link",
    i = $.inArray( toInsert, order ),
    el = lis[ toInsert ],
    new_li;

if( !el && i > -1 ) {
    do el = lis[ order[ ++i ] ];
    while( i < order.length && !el )

    (new_li = document.createElement('li')).id = new_li.innerHTML = toInsert;

    if( el ) ul.insertBefore( new_li, el );
    else ul.appendChild( new_li );
}

Используются преимущества «живых» списков и тот факт, что элементы в списке доступны с помощьюих идентификатор как свойство списка.

JSFIDDLE DEMO


первоначальный ответ:

Это должно сделать это:

var order = ["a-link", "b-link", "c-link", "d-link", "e-link", "f-link"],
    i = 0,
    place = $('ul'),
    el = $('#' + order[i] );

if( !el.length ) {

    $('<li>',{id:order[i]}).prependTo( place );

} else {

    do {
        ++i;
        place = el;
        el = $('#' + order[i] );
    } while( el.length )

    if( i < order.length ) {
        $('<li>',{id:order[i]}).insertAfter( place );
    }
}

JSFIDDLE DEMO


Вотдругой способ сделать это:

var order = ["a-link", "b-link", "c-link", "d-link", "e-link", "f-link"],
    prev,
    el;

$.each( order, function(i,v) {
    prev = el;
    el = $('#' + v);
    if( !el.length ) {
        if( !i ) {
            $('<li>',{id:order[i],text:order[i]}).appendTo('ul');
        } else {
            $('<li>',{id:order[i],text:order[i]}).insertAfter( prev );
        }
        return false;
    }
});

JSFIDDLE DEMO

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...