avalon與masonry的結合

相關組件版本:avalon 1.3.六、masonry 3.1.5php

最近,在公司的項目中,要開發一個使用瀑布流的前臺,衡量了各類解決方案後,仍是以爲masonry最成熟,因此就選用了它。而在以前開發後臺的過程當中,對avalon也用得挺熟手的了,因此此次作前臺也用上。因爲avalon是管dom的,masonry也是管dom的,因此實現兼容的重點就是,讓它們管同一份dom,而不是各管各的。css

個人avalon相關代碼是這樣的:jquery

avalon.define({
      $id: 'masonry',
      article_list: <?php echo $articleList; ?>,
    });

其中的article_list即是存放瀑布流數據的數組,用php生成json格式的字符串輸出,賦給article_list做爲初值(初版數據)。而後,調用avalon的ms-repeat指令來循環渲染瀑布流的dom:ajax

<!-- 瀑布流位置 -->
  <div id="masonry_container" ms-controller="masonry">
    <div id="masonry_content">
        <div class="portfolio" ms-repeat-article="article_list">
          <div class="portfolio-wrapper" ms-click="open_article_modal(article.id)">
              <a> 
                <img ms-attr-src="article.cover_img_url" ms-css-height="article.cover_img_height"> 
              </a>
              <div class="article_follow side_btn"></div>  
              <div class="article_collect side_btn"></div>  
              <div class="article_body">
                <div class="article_meta">
                    <h2>{{article.title}}</h2>
                    <p></p>
                </div>
              </div>
          </div>
        </div>
    </div>
  </div>

在avalon.scan()之後,實例化masonry,初版數據就算是出來了,一切都很正常。json

可是在後面繼續加載數據的時候,就出問題了。個人設計是,判斷當滾動條拉到最下,就觸發事件用ajax讀取第2、3、四……版的數據。數組

一開始我想得很簡單:不就是把ajax獲取到的數據直接添加到avalon的vm裏,讓它自動完成新數據的渲染就行了,而後再從新實例化masonry。這種方案的問題是,因爲「從新實例化masonry」須要的是先把masonry對象destroy()掉,因此就會看到很明顯的閃爍,並且,能夠預想到,當數據愈來愈多的時候,從新實例化的代價就會愈來愈大,所以這種方案是不可取的。app

接着我仔細閱讀了masonry的文檔,發現其原來是有addItems/appended這樣的方法可供調用的,我讀了文檔上的示例代碼(一個小插曲,因爲本人的原生js實在是太不濟,就想着用jquery版的,卻發現不管如何都調不通,大概是由於用了requireJS來模塊化的緣故吧,這裏暫且不提),發現這個方法的原理就是先往dom樹裏添好新的dom節點,而後再將新的dom節點做爲參數傳入addItems/appended。這就使我犯難了,個人dom樹是交給avalon來處理的,又不是本身拼的,哪來dom節點能夠傳給masonry呀?爲了作出一份能夠傳給masonry的dom節點,我也是拼了,用jquery來生成一份dom節點再傳給masonry,但是試了一下,無效呀,masonry根本就沒有控制新增dom節點的位置。dom

這時候我在嘀咕,會不會是avalon還未生成dom節點,masonry就開始「控制」的緣故呢?爲了測試這個可能性,我使用了avalon中的data-repeat-rendered指令,這個指令能夠指定一個函數,在ms-repeat渲染完後再執行,這樣就能夠保證avalon已經生成好dom節點後masonry再介入。測試的結果很使人沮喪,masonry依然沒有控制dom節點的位置,因此應該不是這個問題。ide

最終,在個人測試下,正確的作法是:把avalon生成的dom節點傳給masonry,怎麼實現呢?提及來也很簡單,記錄下拉取新數據前瀑布流已有多少個文塊,也記錄下拉取到多少個文塊,這樣就能夠獲得新增文塊索引的範圍是從幾到幾了;當avalon渲染完ms-repeat後,用jquery獲取瀑布流全部文塊的dom樹,再根據算出來的新增文塊索引範圍,將新增的dom節點取出來後,傳給masonry,就大功告成了!模塊化

相關文章
相關標籤/搜索