ホームページ  >  記事  >  ウェブフロントエンド  >  jqueryはシンプルなウォーターフォールフローレイアウトを実装します

jqueryはシンプルなウォーターフォールフローレイアウトを実装します

高洛峰
高洛峰オリジナル
2016-12-28 10:10:52958ブラウズ

これが冒頭で述べた原則です

滝の流れのレイアウトには、固定カラムと非固定カラムの 2 種類があります。この記事では主に 1 番目のタイプの実装について説明します。

固定列の特徴は、ページがどのように拡大縮小されても、各行の列の合計数が一定であることです。

1 行 4 列の滝の流れは、レイアウトの観点から見ると、4 つの li タグになります。特定のイベント (スクロール バーがスクロールするピクセル数など) を通じてそれを読み取り、データをページに動的に追加します。

データ追加の原則は、liインデックス値に基づいて追加するのではなく、列の中で最も高さが短い列に基づいて動的に追加することです。そうしないと、ページが見苦しくなる (左右の高さが不均一になる) 可能性があります。

この例には、ajax メソッドが含まれています。サーバー環境でも実行可能。

これ以上ナンセンスはありません。スタイルを直接適用します。

<ul id="ul1">
 <li>
  <div>
   <img  src="images/1.jpg" alt="jqueryはシンプルなウォーターフォールフローレイアウトを実装します" >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
   <img  src="images/2.jpg" alt="jqueryはシンプルなウォーターフォールフローレイアウトを実装します" >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
   <img  src="images/3.jpg" alt="jqueryはシンプルなウォーターフォールフローレイアウトを実装します" >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
   <img  src="images/4.jpg" alt="jqueryはシンプルなウォーターフォールフローレイアウトを実装します" >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
</ul>

css

*{
 margin:0;
 padding: 0;
}
ul li{
 list-style: none;
}
#ul1{
 width: 1080px;
 margin: 100px auto 0;
}
li{
 width: 247px;
 float: left;
 margin-right: 10px;
}
li div{
 border:1px solid #000;padding:10px;
 margin-bottom:10px;
}
li div img{
 width: 225px;display: block;
}

基本的な効果は図の通りです:

jqueryはシンプルなウォーターフォールフローレイアウトを実装します

スタイル表示がOKになったら、liのコードを削除します。

次に、ajax を介して動的に追加します。

データはどこから来たのですか?

ここではwookmarkのデータインターフェースが使用されます。

http://www.wookmark.com/api/json/popular?page=1

URLをクリックすると、jsonが取得されます。

情報がたくさんあります。どのように分析するのか?

通常はドキュメントを参照できます。ただし、ドキュメントが手元にない場合は、リンクを参照してください。リターンとは一体何なのか。

function createUrl(num){
 return &#39;http://www.wookmark.com/api/json/popular?page=&#39;+num+&#39;&callback=?&#39;;
}
$(function(){
 $.getJSON(createUrl(1),function(data){
  console.log(data);
 })
})

コンソールの印刷結果は次のとおりです:

jqueryはシンプルなウォーターフォールフローレイアウトを実装します

これは 50 個の画像情報の配列であることがわかります。配列の各要素は json です。この簡単なデモでは、当面はプレビュー属性とタイトル属性を取得するだけで済みます。

レイアウト実装の鍵の 1 つは、最も短い li を決定することです。実際には、最も短い高さ li のインデックス値が必要です。

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
  if($(&#39;li&#39;).eq(i).height()<$(&#39;li&#39;).eq(shortest).height()){
   shortest=i;
  }
 }
 return shortest;
}

次にgetJSONメソッドがあります

$(function(){
 $.getJSON(createUrl(1),function(data){
  //console.log(data);
  for(var i=0;i<dataArr.length;i++){
   var $html=$(&#39;<div><img  src="&#39;+data[i].preview+&#39;" alt="jqueryはシンプルなウォーターフォールフローレイアウトを実装します" ><p>&#39;+data[i].title+&#39;</p></div>&#39;);
   //console.log($(&#39;li&#39;).eq(getShortestLi()).height())
   $(&#39;li&#39;).eq(getShortestLi()).append($html);
  };
  console.log([$(&#39;li&#39;).eq(0).height(),$(&#39;li&#39;).eq(1).height(),$(&#39;li&#39;).eq(2).height(),$(&#39;li&#39;).eq(3).height()])
 })
})

それを再度ロードするとレイアウトが出てきます。シンプルで美しい。

jqueryはシンプルなウォーターフォールフローレイアウトを実装しますこの時点では、すべて問題ないようです。しかし、そこには致命的な問題が潜んでいます。

for ループが問題を引き起こしていますか?

console.log 情報を確認してください。分析のために、4 つの里の高さを配列に入れました。

50 枚の写真は 4 つの列に分割されており、平均の高さは少なくとも 3 ~ 4,000 ピクセルでなければなりません。

画像の読み込み処理が for ループの実行速度よりも遅いため、ループの最後にプログラムが判断する終点はわずか 1,000 ピクセルというとんでもない値になります。デモでの表示は正常ですが、この種のコードはネットワーク速度が悪い場合に作業事故を引き起こす可能性があります。

アイデア 1: 画像が読み込まれているかどうかを判断できます。

タイマーを使用してそれを監視し、それを再帰を使用して実装できます。私の計画は次のとおりです

var index=0;
function LoadPic(index){
 var $html=$(&#39;<div><img  src="&#39;+data[index].preview+&#39;" alt="jqueryはシンプルなウォーターフォールフローレイアウトを実装します" ><p>&#39;+data[index].title+&#39;</p></div>&#39;)
 $(&#39;li&#39;).eq(getShortestLi()).append($html);
 var oImg=$html.find(&#39;img&#39;);
 var t=setInterval(function(){
  if(oImg.height()!=0){//如果加载完了。
   clearInterval(t);
   //console.log([$(&#39;li&#39;).eq(0).height(),$(&#39;li&#39;).eq(1).height(),$(&#39;li&#39;).eq(2).height(),$(&#39;li&#39;).eq(3).height()])
   if(index<50){
    return LoadPic(index+1);
   }else{
    return false;
   } 
  }else{
   console.log(&#39;wait&#39;)
  }
 },50)//每隔50ms监听一次
}
LoadPic(0);

しかし、ユーザーエクスペリエンスの観点から、画像をロードする前に1つの画像がロードされるのを待つのは不親切です。次の。データプロバイダーは、画像の高さをサーバー上で直接処理し、json データで返す必要があります。インターネットの速度が非常に遅い場合、長時間待たなければならないのに、突然すべての写真が表示されるのは奇妙だと思いませんか?特にサードパーティのインターフェース。ロードに失敗すると、大きな問題が発生します。

幸いなことに、サードパーティが画像の幅と高さの情報を提供します。

そのため、返されたデータには幅と高さの値が含まれています。これらを使用すると、固定幅 (255px) と固定高さ (元の高さに比率を掛けたもの) を実現できます。

$(function(){
 $.getJSON(createUrl(1),function(data){
  console.log(data);
  for(var i=0;i<data.length;i++){
    //console.log(data[i].preview);
    var $html=$(&#39;<div><img  src="&#39;+data[i].preview+&#39;" alt="jqueryはシンプルなウォーターフォールフローレイアウトを実装します" ><p>&#39;+data[i].title+&#39;</p></div>&#39;)
    $(&#39;li&#39;).eq(getShortestLi()).append($html);
     
    $html.find(&#39;img&#39;).css(&#39;height&#39;,(data[i].height*225/data[i].width)+&#39;px&#39;);
    $html.find(&#39;img&#39;).css(&#39;width&#39;,&#39;225px&#39;); 
   };
  //console.log([$(&#39;li&#39;).eq(0).height(),$(&#39;li&#39;).eq(1).height(),$(&#39;li&#39;).eq(2).height(),$(&#39;li&#39;).eq(3).height()])
 })
})

実際、私は個人的に、これが最高のユーザーエクスペリエンスを備えた最もシンプルなソリューションだと考えています。

滝の場合は、やはりフローする必要があります

フローのロジック

プルダウン (スクロール) すると、下部の表示領域に入る最初の li が最初にロードされます。

jqueryはシンプルなウォーターフォールフローレイアウトを実装します つまり、最も短い li とページの先頭までの li の高さの合計が、スクロール バーの高さと視覚領域の高さの合計より小さい場合、li はロードがトリガーされます。

liの身長は簡単に見つかります。しかし、li からページの先頭までの最短距離を見つけるにはどうすればよいでしょうか?

ネイティブ メソッドは次のように実装できます:

function getTop(obj){
 var iTop=0;
 while(obj){
  iTop+=obj.offsetTop;
  obj=obj.offsetParent;
 }//累加元素本身和自身所有父级高度偏移值
 return iTop;
}

ただし、この例では jquery を使用しているため、当然独自のメソッドがあります。

obj.offset().top

Scrollイベント

ネイティブ実装メソッドは次のとおりです: window.onscroll=function(){...}

jqueryの実装メソッドは次のとおりです:$(window).scroll(function) ( :)

スクロール イベントが関係するため、簡単に呼び出せるように getJSON 関連の関数を getList() としてカプセル化する必要があります。したがって、再調整する必要があります。

この時のコードはこんな感じです:

(window).scroll(function(){
 var $li=$(&#39;li&#39;).eq(getShortestLi());
 var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;
 //console.log([$li.offset().top+$li.height(),document.documentElement.clientHeight+scrollTop])
 //如果li高度与li到页面顶部的高度之和<可视区高度+滚动距离
 if($li.offset().top+$li.height()<document.documentElement.clientHeight+scrollTop){
   alert(1);
 }
})

このようにすれば実現できそうです。しかし、console.log を見ると、別の問題が見つかりました。

トイレに行くロジック

在触发加载前提时,图片正在加载,期间动了滚动条,就又触发第二次加载,再动一下,就触发第三次,于是短短一瞬间,触发了n次加载。

那就做一个开关吧。

就跟公厕逻辑一样。n个人排队进一个坑位。外面的人想要进去首先得判断门是否锁上了。没锁才能进。进去之后第一件事把门锁上。等如厕完毕,门就打开。后面的人才能进

新设置一个开关bCheck,默认为true。

到触发加载条件时,还要判断bCheck是否为真(门开),为真时才能触发getList()(如厕)。否则return false(只能等)。

getList一开始就把bCheck设为false(如厕前先锁门)。等到getList回调函数执行到尾声。再把bCheck设为true(开门)。

这一段不贴代码了。

总有流完的一天。

当数据结束时(所有人上完厕所),就没有必要再进行加载了(自动把门锁上)。

所以在getJSON回调函数内锁门之后发现进来的是个空数组,那就进行判断,当获取到data的length为空时,直接returnfalse。那么bCheck就永远关上了。

全部代码如下:

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
  if($(&#39;li&#39;).eq(i).height()<$(&#39;li&#39;).eq(shortest).height()){
   shortest=i;
  }
 }
 return shortest;
}
function createUrl(num){
 return 'http://www.wookmark.com/api/json/popular?page='+num+'&callback=?';
}
var bCheck=false;
function getList(n){
 $.getJSON(createUrl(n),function(data){
  if(data.length==0){
   return false;
  }else{
   for(var i=0;ijqueryはシンプルなウォーターフォールフローレイアウトを実装します

'+data[i].title+'

'); $('li').eq(getShortestLi()).append($html); $html.find('img').css('height',(data[i].height*225/data[i].width)+'px'); $html.find('img').css('width','225px'); }; } bCheck=true; }); } $(function(){ var pageNum=1; getList(pageNum); $(window).scroll(function(){ var $li=$('li').eq(getShortestLi()); var scrollTop=document.documentElement.scrollTop||document.body.scrollTop; //console.log([$li.offset().top+$li.height(),document.documentElement.clientHeight+scrollTop]) //如果li高度与li到页面顶部的高度之和<可视区高度+滚动距离 if($li.offset().top+$li.height()

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持PHP中文网!

更多jqueryはシンプルなウォーターフォールフローレイアウトを実装します相关文章请关注PHP中文网!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:jqueryスクロールバープラグイン(カスタマイズ可能)次の記事:jqueryスクロールバープラグイン(カスタマイズ可能)

関連記事

続きを見る