jQuery动态地命令AppendTo

时间:2014-07-01 07:02:51

标签: javascript jquery html appendto

我有以下代码:

HTML:

<ul id="main-menu">
    <li><a href="#page-1" class="slide-item selected">page 1</a></li>
    <li><a href="#page-2" class="slide-item">page 2</a></li>
    <li><a href="#page-3" class="slide-item">page 3</a></li>
    <li><a href="#page-4" class="slide-item">page 4</a></li>
</ul>

<div class="test">
    <div id="page-1" class="page">
    <div class="page-container">
        <h3>page 1</h3>
        <p>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi consequatur deleniti eum illo itaque
            iusto officia soluta, veritatis? Ab aliquam autem cum doloribus eaque eum in itaque natus rem, vero.
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi consequatur deleniti eum illo itaque
            iusto officia soluta, veritatis? Ab aliquam autem cum doloribus eaque eum in itaque natus rem, vero.
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi consequatur deleniti eum illo itaque
            iusto officia soluta, veritatis? Ab aliquam autem cum doloribus eaque eum in itaque natus rem, vero.
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi consequatur deleniti eum illo itaque
        </p>
        </div>
    </div>
</div>

JQUERY:

    $.fn.insertAt = function(index, elements){
    var children = this.children();
    if(index >= children.size()){
        console.log(index+'>='+children.size());
        this.append(elements);
        return this;
    }
    var before = children.eq(index);
    $(elements).insertBefore(before);
    return this;
}; //http://upshots.org/javascript/jquery-insert-element-at-index

jQuery('.slide-item').on('click', function(){
        var item = jQuery('a[href="'+jQuery(this).attr('href')+'"]').parent();
        var index = jQuery("ul li").index(item);
        //console.log(index);
        var target = jQuery(this).attr('href').substr(1);

        if(jQuery(jQuery(this).attr('href')).length){
            console.log('loaded');
        }else {
            jQuery.get("pages/"+target+".html", function(data){
                jQuery('.test').insertAt(index, data);
            });
        }

        return false;
    });

基本上你可能会看到根据你点击的链接加载一个页面,现在我的实际问题是:

反正是否要保持秩序?

例如,如果我按此顺序点击链接1,4,2,3那么这就是页面附加到页面的顺序:

<div id="page-1" class="page">
<div id="page-4" class="page">
<div id="page-2" class="page">
<div id="page-3" class="page">

但是我需要它独立于你单击链接的顺序..所以例如,如果我点击1,3,2,4然后我需要页面按顺序追加(1,2,3,4 ):

<div id="page-1" class="page">
<div id="page-2" class="page">
<div id="page-3" class="page">
<div id="page-4" class="page">

我最近尝试通过索引来实现,通过获取所点击的项目li的索引,然后尝试使用insertAt函数,我发现here在该索引处插入div ...但它确实不完全工作,例如,如果我点击4然后3在4之后附加。

任何帮助都会受到极大的赞赏。

8 个答案:

答案 0 :(得分:2)

我建议您通过为每个页面创建空占位符DIV来简化整个系统。该订单已经到位。

JSFiddle:http://jsfiddle.net/TrueBlueAussie/R2T4Z/4/

// Use wrapped DOM ready event to provide local $ for jQuery
jQuery(function ($) {
    $('.slide-item').on('click', function () {
        var $link = $(this);
        var target = $link.attr('href').substr(1);

        // If the div has any content it is "loaded" (if you know the page has child elements use children().length as it will be faster)
        if ($('#' + target).html().length) {
            console.log('loaded');
        } else {
            // Dummy test code - REMOVE THIS
            $('#' + target).html("I AM LOADED:" + target);
            // End dummy test code
            $.get("pages/" + target + ".html", function (data) {
                $('#' + target).html(data);
            });
        }

        return false;
    }).each(function (index) {
        // create an empty placeholder DIV (in order) with unique matching id for each new entry
        var $link = $(this);
        var id = $link.attr("href").substr(1);
        // If page not already present...
        if (!$('#' + id).length) {
            $('.test').append($('<div>').attr("id", id));
        }
    });
});

*注意:jQuery(function ($) {YOU CODE HERE});jQuery(document).ready($){YOUR CODE HERE});的快捷方式,并提供了本地作用域$,因此您的jQuery代码更短。

更新:http://jsfiddle.net/TrueBlueAussie/ugZST/12/

经过多次讨论后,要求还需要使用水平滑块。现有的是一次性类型并且与动态内容不兼容,所以我也使用slideToPage函数替换它,该函数使用绝对动画将页面带入和移出视图:

function slideToPage($page){
    var $wrapper = $('.wrapper');
    var width = $wrapper.outerWidth();
    var height = $wrapper.outerWidth();

    // Set size of all children and stop previous animations
    $wrapper.children().css({width: width, height: height}).stop();

    // Find the current page (positioned at 0)
    var $currentpage = $wrapper.find('.currentpage');
    if ($page.is($currentpage)){
        console.log("Stay on current page");
        return;
    }
    console.log("$currentpage.index() " + $currentpage.index());
    console.log("$page.index() " + $page.index());

    // Is the new page index before or after (left or right scroll)
    var slideRight = $page.index() > $currentpage.index();
    var delta = slideRight ? 1 : -1;

    // Position offscreen (to left or right of the screen)
    $page.css({left: delta * width});

    // Animate new panel to positon 0
    $page.animate({left: 0}, 1000).show();

    // Animation old panels offscreen (left or right) then hide
    $currentpage.animate({left: -delta * width}, 1000, function(){
        $currentpage.hide();
    });

    $currentpage.removeClass('currentpage');
    $page.addClass('currentpage');

    // hide all other pages (just to be sure)
    $wrapper.children().not($currentpage).not($page).hide();
}

// Use wrapped DOM ready event to provide local $ for jQuery
jQuery(function ($) {
    $('.scrollitem').on('click', function () {
        var $link = $(this);
        var target = $link.attr('href').substr(1);

        // If the div has any content it is "loaded" (if you know the page has child elements use children().length as it will be faster)
        var $page = $('#' + target);
        var $target = $page.find('.page-container');
        if ($target.html().length) {
            console.log('loaded');
            slideToPage($page);
        } else {
            // Dummy test code - REMOVE THIS
            $target.html("I AM LOADED:" + target + "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi consequatur deleniti eum illo itaque Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi consequatur deleniti eum illo itaque Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi consequatur deleniti eum illo itaque");
            slideToPage($page);
            $page.css('display', '');
            // End dummy test code
            $.get("pages/" + target + ".html", function (data) {
                $target.html(data);
                slideToPage($page);
                $page.css('display', '');
            });
        }

        return false;
    }).each(function (index) {
        // create an empty placeholder DIV (in order) with unique matching id for each new entry
        var $link = $(this);
        var id = $link.attr("href").substr(1);
        // If page not already present...
        if (!$('#' + id).length) {
            $('.wrapper').append($('<div class="page"><div class="page-container"></div></div>').attr("id", id).css('display', 'none'));
        }
    });
});

答案 1 :(得分:1)

您的插入功能对您没有帮助。如您所见,单击第4页然后第3页没有正确排序,因为insert-at函数根据子元素的索引插入dom元素。这意味着,如果你有一个像[page3,page5]这样的列表,那么在索引n处插入任何后续页面n都会明显失效。

这个问题有很多解决方案,很难确定哪个是最适合您用例的选项,但一个简单的解决方案是简单地遍历当前列表,直到第n个索引有一个页码大于n,然后将其插入n。在计算机科学中,我们称之为在线插入排序。您可以在此处阅读:http://en.wikipedia.org/wiki/Insertion_sort

这是一个示范:

$.fn.insertAt = function(index, elements){
    var children = this.children();
    if(index >= children.size()){
        console.log(index+'>='+children.size());
        this.append(elements);
        return this;
    }
    var before = children.eq(index);
    $(elements).insertBefore(before);
    return this;
}; //http://upshots.org/javascript/jquery-insert-element-at-index

jQuery('.slide-item').on('click', function(){
    var item = jQuery('a[href="'+jQuery(this).attr('href')+'"]').parent();
    var index = jQuery("ul li").index(item);
    //console.log(index);
    var target = jQuery(this).attr('href').substr(1);

    if(jQuery(jQuery(this).attr('href')).length){
        console.log('loaded');
    }else {
        //jQuery.get("pages/"+target+".html", function(data){
        //    jQuery('.test').insertAt(index, data);
        //});

        // the insert page number happens to be the index
        var data = '<div id="' + target + '" class="page">' + target + ' content</div>';
        var toInsertPageNumber = index;
        var didInsert = false;
        jQuery('.test').children().each(function(k, v) {
            var currentPageNumber = parseInt($(v).attr('id').replace('page-', ''), 10);

            if (currentPageNumber > index) {
                jQuery('.test').insertAt(k, data);      
                didInsert = true;
                return false;
            }
        });

        // if we didn't insert anything, then it goes to the end of the list.
        if (!didInsert) {
            jQuery('.test').append(data);
        }
    }

    return false;
});

这是包含上述代码的小提琴:http://jsfiddle.net/aDtV5/

答案 2 :(得分:1)

不需要占位符。

jsfiddle:http://jsfiddle.net/Neverever/43gn9/

function insertData(id, data){
    // locate next 'div' and insert before it
    var found = $("li:has(a[href='" + id + "']) ~ li a").get().some(function(elm, idx) {
        var nextDiv = $($(elm).attr('href'));
        return nextDiv.length && nextDiv.before(data);
    });

    // if not found, append to .test
    if(!found)
        $(".test").append(data);

}

jQuery(function($) {
    $('.slide-item').on('click', function(){
        var self = $(this),
            id = self.attr('href'),
            target = id.substring(1);

        if($(id).length) {
            console.log('loaded');
        } else {

            // use jsFiddle ajax api call to return dummy HTML
            $.post("/echo/html/", { html : '<div id="'+target+'">'+target+'</div>'}, function(data) {
                insertData(id, data);
            });

            // uncomment the following for your actual ajax request
            /*
            $.get("pages/"+target+".html", function(data){
                insertData(id, data);
            });
            */
        }
        return false;
    });
});

答案 3 :(得分:1)

由于DOM节点列表实现了类似于数组的构造,因此您可以对它们进行排序。你可以把它变成一个jQuery&#34;插件&#34;非常容易:

function sortNodes(nodes, compare) {
    if(nodes instanceof jQuery) nodes = nodes.get();
    nodes.sort(compare);
    jQuery.each(nodes, function(i, node) {
        node.parentNode.appendChild(node);
    });
}

然后你会像这样使用它:

// replace this line in your code:
jQuery('.test').insertAt(index, data);

// with this code:
var $test = jQuery('.test');
$test.append( data );
sortNodes( $test.children(), function(a, b) {
    return a.id > b.id;
});

说明:将节点列表传递给sortNodes方法。在您的情况下,传入一个页面列表。您的HTML结构是这样的:

<div class="test">
   <div id="page-4" class="page"></div>
   <div id="page-1" class="page"></div>
   <div id="page-3" class="page"></div>
   <div id="page-2" class="page"></div>
</div>

所以我们使用这一行传递页面列表:

jQuery('.test').children();

然后根据&#39;比较&#39;对每个节点进行排序。函数(阅读关于自己排序数组)。在这种情况下,我们比较节点ID,以便节点按其ID按字母顺序排序(例如'page-2' > 'page-1')。

......小提琴:

http://jsfiddle.net/ryanwheale/FpkgH/

答案 4 :(得分:0)

这是一个可以解决这个问题的函数:

//check by comparing order number
function insert(page){
    //extract order number from element to be inserted
    var placeId = parseInt($(page).attr('id').substr($(page).attr('id').length - 1));
    //loop through each existing page
    $('.page').each(function(){
        //extract order number of current loop iteration
        var id = parseInt($(this).attr("id"));
        //if currently existing item has higher ID than the one to be inserted
        //insert new page before(this works because we can assume order)
        if(id > placeId){
            $([NEW_PAGE]).insertBefore($(this));
            return;
        }
        //in case your trying to load an existing page
        if(id === placeId){return;}
    });
    //page to be loaded is bigger than any already loaded
    $([NEW_PAGE]).insertAfter($('.page').last());
}

答案 5 :(得分:0)

如果这是你要找的...... 也许你可以试试这个..

 <style>
 .hidden{
   display:none;
 }
</style>

<ul id="main-menu">
<li><a href="#page-1" class="slide-item selected">page 1</a></li>
<li><a href="#page-2" class="slide-item">page 2</a></li>
<li><a href="#page-3" class="slide-item">page 3</a></li>
<li><a href="#page-4" class="slide-item">page 4</a></li>
</ul>



<div id="page-1" class="page hidden">
<div id="page-2" class="page hidden">
<div id="page-3" class="page hidden">
<div id="page-4" class="page hidden">


<script>
 var content = "Content of ";
 $("#main-menu li").on("click",function(e){
   var id = e.target.hash.substring(1);
   $("#"+id).removeClass('hidden')
   .append("div")
   .addClass("page-container")
   .append("h3").text(id)
   .append("p")
   .text(content);
});
</script>

将“内容”替换为您要在文字方法中显示的内容。

答案 6 :(得分:0)

您可以使用查找id小于要插入页面的元素的函数调用.filter()。然后在找到最后一个div之后插入页面。

function addPage(id, page) {
    if (!$('#' + id).length) {
        // find the last page div with id smaller than target id
        $prevDiv = $('div.page', '.test').filter(function () {
            return $(this).attr('id') < id;
        }).last();

        // and append the new page after it
        $prevDiv.after(page);
    }
}

请参阅JSFiddle

答案 7 :(得分:-2)

您可以将点击的索引作为URL参数发送,然后使用数据(来自服务器)将其发送回客户端。然后,您可以将收到的数据附加到正确的位置。另外一点是,如果你按照这个顺序点击链接1,4,2,3,你就不能期望结果是相同的顺序,因为ajax调用是异步执行的。

jQuery('.slide-item').on('click', function(){
var target = jQuery(this).attr('href').substr(1);
jQuery.get("pages/"+target+".html", function(data){

    if($('.test').length == 0 )
    {
        $('.test').append(data);
    }
    else
    {
        $('.test').each(function(key,val){
          var id = $(val).attr("id");
          var index = id.split("-")[1];
          if(index <= newIndex)
          {
            //here newIndex is clicked link should come from server
            jQuery(data).insertAfter($(this));
          }
        });
    }

});
return false;
});