簡體   English   中英

動態Javascript數組.length

[英]Dynamic Javascript Array .length

我想要做的是將新的“ .post”(已通過無限滾動腳本檢索到)推入包含所有“ .post”的數組中。

完整代碼: https//gist.github.com/sxxfi/8296403
現場演示: http//soof-show.tumblr.com (使用鍵盤箭頭鍵瀏覽帖子)

最初,五個“ .post”顯示在“ .content” div中,然后每次單擊“更多”按鈕時,都會在“ .content”中再添加五個“ .post”。

問題是數組長度不計入新的“ .post”,因此它會繼續循環第一個5。

如果能解決這個問題,請先謝謝您。

使用Javascript:

        $(document).ready(function(){

        // I N F I N I T E  S C R O L L
        $('.content').infinitescroll({
          navSelector  : ".navigation",
          nextSelector : ".navigation .next_page",
          itemSelector : ".content .post",
          behavior: "twitter"
        });

        $(window).unbind('.infscr');

        $('.next_page').click(function(){
          $(document).trigger('retrieve.infscr');
          return false;
        });

        $(document).ajaxError(function(e,xhr,opt){
          if (xhr.status == 404) $('.next_page').remove();
        });


        // I M A G E  S L I D E R
        var obj = $(".post");
        var arr = $.makeArray(obj);
        var lastDiv = $(".post");
        var indexNum = arr.length-1;

        $(window).keydown(function (e) {
            if (e.keyCode == 37) { // L E F T
                lastDiv.fadeOut(800);
                indexNum--;
                if (indexNum == -1) indexNum = arr.length-1; //if goes beyond first post, goto the last post
                $(arr[indexNum]).appendTo(".postslide").fadeIn(800);

                // C E N T E R
                var width = $(arr[indexNum]).width();
                var marginLeft = width / 2;
                $(arr[indexNum]).css('margin-left', -marginLeft);
            }

            if (e.keyCode == 39) { // R I G H T
                $('#instruction').fadeOut();
                lastDiv.fadeOut(800);
                indexNum++;
                if (indexNum == arr.length) indexNum = 0; //if goes beyond last post, goto the first post
                $(arr[indexNum]).appendTo(".postslide").fadeIn(800);

                // C E N T E R
                var width = $(arr[indexNum]).width();
                var marginLeft = width / 2;
                $(arr[indexNum]).css('margin-left', -marginLeft);
            }
        });

    });

更新:

        $(document).ready(function(){


        // I N F I N I T E  S C R O L L
        $('.content').infinitescroll({
          navSelector  : ".navigation",
                         // selector for the paged navigation (it will be hidden)
          nextSelector : ".navigation .next_page",
                         // selector for the NEXT link (to page 2)
          itemSelector : ".content .post",
                         // selector for all items you'll retrieve
          behavior: "twitter"
        });

        // kill scroll binding
        $(window).unbind('.infscr');

        // manual click 
        $('.next_page').click(function(){
          $(document).trigger('retrieve.infscr');
          return false;
        });

        // remove the paginator done
        $(document).ajaxError(function(e,xhr,opt){
          if (xhr.status == 404) $('.next_page').remove();
        });




        // I M A G E  S L I D E R
        var obj = $(".post");
        var indexNum = obj.length-1;
        var lastDiv = $(".post");



        $(window).keydown(function (e) {

            if (e.keyCode == 37) { // L E F T

                lastDiv.fadeOut(800);
                indexNum--;
                if (indexNum == -1) indexNum = obj.length-1; //if goes beyond first post, goto the last post
                $(obj[indexNum]).appendTo(".postslide").fadeIn(800);

                // C E N T E R
                var width = $(obj[indexNum]).width();
                var marginLeft = width / 2;
                $(obj[indexNum]).css('margin-left', -marginLeft);
            }

            if (e.keyCode == 39) { // R I G H T

                $('#instruction').fadeOut();
                lastDiv.fadeOut(800);
                indexNum++;
                if (indexNum == obj.length) indexNum = 0; //if goes beyond last post, goto the first post
                $(obj[indexNum]).appendTo(".postslide").fadeIn(800);

                // C E N T E R
                var width = $(obj[indexNum]).width();
                var marginLeft = width / 2;
                $(obj[indexNum]).css('margin-left', -marginLeft);
            }
        });

    });

jQuery選擇器在調用jQuery函數時查詢DOM,因此它們在給定的時刻選擇與選擇器匹配的元素。

即使稍后將與選擇器匹配的新元素添加到DOM,也不會選擇它們,因為沒有任何內容通知jQuery重新評估選擇器,即使這樣做,jQuery也沒有內部狀態保存所有已創建的jQuery對象。 這意味着選擇器沒有激活

您的主要問題是,您永遠不會更新所選DOM元素的數組,因此即使將新元素添加到DOM中,您仍然會在原始數組上循環。

更新jQuery對象很容易,您只需在代碼中的任何時間調用obj = $(".post") ,並且obj變量將被更新。 我們只需要弄清楚何時調用它。

由於您使用的是Infinite Scroll來加載新元素,因此我們需要查看它的文檔 ,或者由於文檔中目前存在大量漏洞,因此最好查看源代碼

看一下infinitescroll函數:

$.fn.infinitescroll = function infscr_init(options, callback) {
    ...

第二個參數稱為callback ,在檢查源代碼以及該參數的傳遞和調用方式后,您可以看到它將在檢索到新元素之后被調用。 讓我們嘗試一下此參數:

$('.content').infinitescroll({
    navSelector : ".navigation",
    // selector for the paged navigation (it will be hidden)
    nextSelector : ".navigation .next_page",
    // selector for the NEXT link (to page 2)
    itemSelector : ".content .post",
    // selector for all items you'll retrieve
    behavior: "twitter"
}, function () {
    obj = $(".post");
    console.log("Current length is: " + obj.length); //this line is not necessary, just here for debug purposes.
});

假設變量obj已經存在,這將更新其值。

請注意,在此答案的先前版本中,我將此回調函數稱為recountPosts() 后來我決定,它只能是內聯匿名函數,因為它只能從一個地方調用。

您快要完成了,但是...根據此選擇器還有其他變量。 arrlastDiv 在檢查您的源代碼后,似乎它們都不是必需的:

  1. arr是由jQuery對象選擇的元素組成的數組 ,盡管jQuery對象不是數組 ,但它具有從零開始的數字索引器和length屬性,就像數組一樣 ,因此您可以在代碼中的任何地方用obj替換arr

  2. lastDiv的名稱具有誤導性。 它擁有與obj相同的元素,而不僅僅是最后一個。 因此,它也可以用obj代替。

因此,可以將聲明變量的部分縮小為:

// I M A G E  S L I D E R
var obj = $(".post");
var indexNum = obj.length-1;

我還查看了您的keydown事件處理程序。 里面有很多重復的代碼。 以后很容易引入錯誤(實際上您已經有一個錯誤:如果在開始時按左鍵而不是按右鍵,則鍵盤的初始圖像不會消失)。

讓我為您重組一下:

$(window).keydown(function (e) {
    if (e.keyCode === 37) { // L E F T
        indexNum--;
    }

    if (e.keyCode === 39) { // R I G H T
        indexNum++;
    }

    if (e.keyCode === 37 || e.keyCode === 39) {
        $('#instruction').fadeOut();

        obj.fadeOut(800);

        if (indexNum === -1) {
            indexNum = obj.length-1; //if goes beyond first post, goto the last post
        }
        if (indexNum === obj.length) {
            indexNum = 0; //if goes beyond last post, goto the first post
        }

        $(obj[indexNum]).appendTo(".postslide").fadeIn(800);

        var width = $(arr[indexNum]).width();
        var marginLeft = width / 2;
        $(obj[indexNum]).css('margin-left', -marginLeft);
    }
});

完成了!


不,當然沒有完成。 這還遠遠沒有完成,還有很多很多事情需要改進。

  • 就像在每次按鍵時刪除丑陋的重新計算margin-left並用幾行CSS來解決一樣。 經驗法則:如果可以使用CSS而不是javascript解決某些問題,則應該解決。

  • 或者像在$(".postslide")而不是$(".content") infinitescroll(...)上調用infinitescroll(...)並從fadeIn()之前刪除完全不必要的.appendTo(".postslide")一樣,因為元素已經附加,重新附加它們是浪費資源。

  • 或者將常量(例如800 ms的淡入長度)移動到代碼的開頭,為它們提供一個變量,例如var fadeLength = 800; 並使用它。

而且我很確定還有很多其他事情可以做得更好,但這就是編程的方式:)

祝您編碼愉快!

編輯:

因此,您還希望僅在幻燈片的末尾才顯示更多按鈕。 您已經寫了這個:

if (indexNum === 14){
  $('.next_page').html('<img src="http://long_url/">');
}

為什么將14硬編碼到源代碼中? 您為什么還要關心要加載多少圖片以及將要加載多少圖片? 代碼的給定部分僅需要知道您是否最后。 如果您有關於要加載的幻燈片數量的變量,則可以輕松地檢查是否位於最后一個索引處。 確實擁有該變量obj.length

if (indexNum === obj.length-1){
  $('.next_page').html('<img src="http://long_url/">');
}

這樣,如果是30、45或9001st,則更多按鈕將出現在最后一張幻燈片上,而不再需要關注。

加載新內容后,您還需要此按鈕消失。 這進入了infinitescroll的回調:

function () {
    obj = $(".post");
    console.log("Current length is: " + obj.length); //this line is not necessary, just here for debug purposes.
    $('.next_page').html('');
}

您可以做的另一件事是代替顯示more按鈕,而可以從代碼中觸發more事件。 這樣,當用戶到達最后一張幻燈片時,新幻燈片將自動加載。

同樣,只有在實際上有更多幻燈片要加載時才需要發生這種情況。 您可以檢查當前狀態的isDone屬性, isDone屬性會告訴您是否“無限滾動完成”,因此不再需要加載任何元素。

$('.content').data('infinitescroll').options.state.isDone === false

因此,除了顯示更多按鈕的部分,您可以編寫以下代碼:

if (indexNum === obj.length-1 && !$('.content').data('infinitescroll').options.state.isDone){
  $(document).trigger('retrieve.infscr');
}

問題:

您要在頁面加載后立即設置值,而在滾動或其他鍵綁定時不更新它

解:

    // I M A G E  S L I D E R
        var obj = $(".post");
        var arr = $.makeArray(obj);
        var lastDiv = $(".post:last");
        var indexNum = arr.length-1;


        $(window).keydown(function (e) {
                        obj = $(".post");
                        arr = $.makeArray(obj);
                        lastDiv = $(".post:last");
                        indexNum = arr.length-1;

                        //other code

        });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM