Maison >interface Web >js tutoriel >Explication détaillée de Javascript pour implémenter les compétences absolues layout_javascript du flux en cascade
Le débit en cascade doit être populaire depuis quelques années. D'abord, ce fut la vague déclenchée par Pinterest, puis le design domestique s'est multiplié, avec de nombreux exemples de cascades surgissant, comme Mogujie, Mark's (mais récemment, il s'est impliqué dans la pornographie, et il semble avoir été taquiné), et Le « Wow » de Taobao ». Ce sont d'excellents exemples, et aujourd'hui nous allons parler du débit de cascade.
1. Disposition absolue :
Principe de mise en œuvre de JS
En fait, la principale difficulté du style cascade est de savoir comment organiser soigneusement les images dans les colonnes correspondantes et quand commencer à actualiser et charger les images.
La logique et l'algorithme principaux pour organiser soigneusement les images consistent d'abord à obtenir combien de colonnes peuvent être placées dans le conteneur, puis, par calcul, à stocker la hauteur de la première colonne, puis à parcourir les hauteurs restantes (à l'exception des éléments du première colonne) et placez-les respectivement. Entrez la colonne avec la plus petite hauteur. Ajoutez un par un, et enfin terminez le parcours.
Les paramètres pour démarrer l'actualisation sont très simples. L'actualisation en cascade n'est liée qu'à un seul événement, à savoir window.onscroll. L'algorithme principal est que lorsque la page glisse à la hauteur la plus basse, elle commence à charger les nœuds et à les ajouter. Bien entendu, le nombre de nœuds ajoutés n’est pas fixe.
Commençons par le code. Je vais l'expliquer en trois parties. L'une est la disposition des images, l'autre définit la position de chargement. De plus, j'ajouterai un chargement réactif.
1. Disposition des images
var $ = function() { return document.querySelectorAll.apply(document, arguments); } var arrHeight = []; //得到分列的高度 var columns = function() { //计算页面最多可以放多少列 var containerW = $("#main")[0].clientWidth, pinW = $(".pin")[0].offsetWidth; return Math.floor(containerW / pinW); } var getIndex = function(arr) { //获得最小高度的index var minHeight = Math.min.apply(null, arr); //获得最小高度 for (var i in arr) { if (arr[i] === minHeight) { return i; } } } //根据列数确定第一排img的高度并放入数组当中。 var setCenter = (function() { //通过列数设置宽度 var main = $('#main')[0]; //获得罩层 var getPadding = function() { //设置padding var col = columns(); //获得最后一列 var padding = main.clientWidth - col * $('.pin')[0].offsetWidth; return padding / 2; } var getComputedStyle = function(ele) { //兼容IE的支持情况 if (window.getComputedStyle) { return window.getComputedStyle(ele); } else { return ele.currentStyle; } } var getPinPad = function() { //获得pin的padding值 var pin = $(".pin")[0]; return parseInt(getComputedStyle(pin).paddingLeft); } return function() { //设置宽度 main.style.padding = `0 ${getPadding()}px 0 ${getPadding()-getPinPad()}px`; } })(); var overLoad = function(ele) { var index = getIndex(arrHeight), minHeight = Math.min.apply(null, arrHeight), //获取最小高度 pins = $('.pin'), style = ele.style; style.position = "absolute"; style.top = minHeight + "px"; //设置当前元素的高度 style.left = pins[index].offsetLeft + "px"; arrHeight[index] += ele.offsetHeight; } //初始化时执行函数 var init = function() { var pins = $(".pin"), col = columns(); setCenter(); //设置包裹容器的宽度 for (var i = 0, pin; pin = pins[i]; i++) { if (i < col) { //存储第一排的高度 arrHeight.push(pin.offsetHeight); } else { overLoad(pin); //将元素的位置重排 } } }
Il y a un total de 7 fonctions (grandes fonctions) et une variable. Parlons de l'idée. Tout d'abord, la fonction exécutée après le chargement de la page est init. Il faut savoir qu'un programme js doit avoir son entrée. La clé dépend de la façon dont vous la trouvez. Ensuite, nous approfondissons le corps de la fonction init et observons. La logique métier exécutée dans init consiste à stocker la hauteur de la première rangée d'éléments, puis à réorganiser les éléments restants. Utilisez la fonction columns pour obtenir le nombre maximum de colonnes pouvant être placées dans la fenêtre actuelle, puis définissez le centre du conteneur (réglez-le simplement via le remplissage). Ensuite, parcourez la zone de cellule de l'épingle, stockez la hauteur de la première. rangée d'éléments dans le tableau arrHeight et ajoutez le reste. Les éléments ci-dessous sont réorganisés. Il n'est pas nécessaire d'expliquer d'autres fonctions. Concentrons-nous sur la fonction overLoad.
2. surcharge
var overLoad = function(ele) { var index = getIndex(arrHeight), minHeight = Math.min.apply(null, arrHeight), //获取最小高度 pins = $('.pin'), style = ele.style; style.position = "absolute"; style.top = minHeight + "px"; //设置当前元素的高度 style.left = pins[index].offsetLeft + "px"; arrHeight[index] += ele.offsetHeight; }
Il existe une fonction getIndex dans overLoad pour obtenir l'index de la hauteur minimale, puis vous pouvez définir la position de l'élément ele entrant (le positionnement absolu est la valeur px de la hauteur minimale dans le tableau, et). left est défini pour la première ligne. La position de la marge gauche de l'élément Index. Enfin mettez à jour la hauteur, ok !!! ça suffit.
3. Définir l'emplacement de chargement
var dataInt = [{ 'src': '1.jpg' }, { 'src': '2.jpg' }, { 'src': '3.jpg' }, { 'src': '4.jpg' }, { 'src': '1.jpg' }, { 'src': '2.jpg' }, { 'src': '3.jpg' }, { 'src': '4.jpg' }]; function isLoad() { //是否可以进行加载 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop, wholeHeight = document.documentElement.clientHeight || document.body.clientHeight, point = scrollTop + wholeHeight; //页面底部距离header的距离 var arr = $('.pin'); var lastHei = arr[arr.length - 1].getBoundingClientRect().top; return (lastHei < point) ? true : false; } //处理滑动 var dealScroll = (function() { var main = $('#main')[0], flag = true; return function() { if (isLoad() && flag) { for (var i = 0, data; data = dataInt[i++];) { var div = document.createElement('div'); div.innerHTML = temp(data.src); div.className = "pin"; main.appendChild(div); overLoad(div); //和上面的overload有耦合性质 } flag = false; setTimeout(function() { //控制滑行手速,时间越长对速度的滑动时间影响越大。 flag = true; }, 200); } } })(); function temp(src) { return ` <div class="box"> <img src="http://cued.xunlei.com/demos/publ/img/P_00${src}"/> </div> `; }
En fait, l'essentiel est dans la partie précédente. Il s'agit simplement d'un moyen de charger des données. Bien sûr, vous pouvez cliquer pour charger (déclenchement manuel), ou d'autres méthodes de chargement. Bien entendu, la manière dont vous le configurez dépend entièrement de vous. Par conséquent, suivez la tendance et faites toujours défiler vers le bas pour charger. Continuez et recherchez l'entrée function->dealScroll. La tâche de cette fonction est de déterminer si le chargement peut être effectué via la fonction isload. Jetons un coup d'œil à la fonction isload. C'est le point clé du chargement progressif.
function isLoad() { //是否可以进行加载 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop, wholeHeight = document.documentElement.clientHeight || document.body.clientHeight, point = scrollTop + wholeHeight; //页面底部距离header的距离 var arr = $('.pin'); var lastHei = arr[arr.length - 1].getBoundingClientRect().top; return (lastHei < point) ? true : false; }
Par calcul, la position du bas de la page depuis la fenêtre (partie inférieure de la barre d'outils) est comparée à la position absolue du dernier élément. Si la distance de glissement dépasse, le chargement est activé.
ouais~ C'est fini.
retour à dealScroll
L'étape suivante consiste à regarder la partie chargement. Il n'y a en fait rien à dire sur cette partie. Il s'agit de créer un nœud div, puis de le placer à la fin du conteneur, et d'utiliser la fonction overLoad pour gérer la position du. nœud. De plus, à la fin de la fonction, j'ai mis en place une astuce pour contrôler la vitesse de glissement. En limitant la fonction, je peux éviter que la requête soit trop lente et que l'utilisateur envoie des requêtes à plusieurs reprises, provoquant un gaspillage de ressources.
Ensuite, cette partie peut prendre fin.
4. Réactif
La dernière partie est la réactivité. Cette partie est également très simple. Tant que vous faites un bon travail d'encapsulation, en fait, cette partie ajoute simplement un événement de redimensionnement. Continuons à chercher la fonction d’entrée.
var resize = (function() { var flag; return function(fn) { clearTimeout(flag); flag = setTimeout(function() { //函数的节流,防止用户过度移动 fn(); console.log("ok") }, 500); } })();
De même, l'idée de limitation des fonctions est utilisée ici. Il faut savoir qu'en tant que programmeur, ne pensez jamais que les utilisateurs ne peuvent rien faire de stupide. Par exemple, lorsque vous n'avez rien à faire, faites glisser la fenêtre du navigateur vers. jouer, zoomer, dézoomer, puis agrandir... En fait, je fais souvent ça, parce que je n'ai pas de petite amie et que j'en ai marre d'écrire du code, alors je fais simplement glisser le navigateur pour jouer. Par conséquent, compte tenu des besoins de notre chien célibataire, il est très nécessaire d’utiliser la limitation des fonctions. Si les chaussures pour enfants vous intéressent, vous pouvez vous référer à mon article précédent pour en savoir plus. Pour expliquer, la fonction de rappel fait ici référence à la fonction init, mais certaines modifications doivent être apportées à init. Voir les détails.
var update = function(ele) { //当resize的时候,重新设置 ele.style.position = "initial"; } //初始化时执行函数 var init = function() { var pins = $(".pin"), col = columns(); arrHeight = []; //清空高度 setCenter(); //设置包裹容器的宽度 for (var i = 0, pin; pin = pins[i]; i++) { if (i < col) { //存储第一排的高度 arrHeight.push(pin.offsetHeight); update(pin); } else { overLoad(pin); //将元素的位置重排 } } }
Une mise à jour doit être ajoutée ci-dessus pour mettre à jour la nouvelle première rangée d'éléments.
Ensuite, vous pouvez simplement le déplacer et l'utiliser.
Il s'agit certainement de l'essentiel du contenu de la mise en page. Pour une autre méthode de mise en page du flux en cascade JavaScript, veuillez vous référer à l'article suivant "Explication détaillée de l'implémentation JavaScript de la mise en page du flux en cascade" .