Cet article présente principalement en détail l'IndexList des effets des terminaux mobiles. Il a une certaine valeur de référence. Les amis intéressés peuvent s'y référer. J'espère que cela pourra aider tout le monde.
est écrit devant
Suite à la précédente présentation sur l'effet mobile, cette fois j'expliquerai le principe de mise en œuvre d'IndexList. L'effet est le suivant :
Veuillez consulter le code ici : github
Swiper pour l'effet mobile
Sélecteur pour l'effet mobile
cellSwiper pour les effets mobiles
1. Analyse de base
Le principe général est que lorsque vous cliquez ou faites glisser la barre d'index à droite, get Cliquez sur la valeur d'index pour faire glisser le contenu de gauche vers la position correspondante. Comment glisser vers une position spécifique, voir la répartition ci-dessous :
1.1 Code HTML de base
<p class="indexlist"> <ul class="indexlist-content" id="content"> <!-- 需要生成的内容 --> </ul> <p class="indexlist-nav" id="nav"> <ul class="indexlist-navlist" id="navList"> <-- 需要生成的索引条 --> </ul> </p> <p class="indexlist-indicator" style="display: none;" id="indicator"></p> </p>
1.2 Initialisation DOM
En raison du fait que indexList dans la bibliothèque de composants Ele.me utilise le composant vue pour générer du DOM, j'utilise grossièrement javascript pour simuler la génération DOM ici.
// 内容填充 function initialDOM() { // D.data 获取内容数据 var data = D.data; var contentHtml = ''; var navHtml = ''; // 初始化内容和NAV data.forEach(function(d) { var index = d.index; var items = d.items; navHtml += '<li class="indexlist-navitem">'+ index +'</li>'; contentHtml += '<li class="indexsection" data-index="'+ index +'"><p class="indexsection-index">'+ index +'</p><ul>'; items.forEach(function(item) { contentHtml += '<a class="cell"><p class="cell-wrapper"><p class="cell-title"><span class="cell-text">'+ item +'</span></p></p></a>'; }); contentHtml += '</ul></li>'; }); content.innerHTML = contentHtml; navList.innerHTML = navHtml; } // 样式初始化 if (!currentHeight) { currentHeight = document.documentElement.clientHeight -content.getBoundingClientRect().top; } // 右边索引栏的宽度 navWidth = nav.clientWidth; // 左边内容的初始化高度和右边距 // 高度为当前页面的高度与内容top的差值 content.style.marginRight = navWidth + 'px'; content.style.height = currentHeight + 'px';
1.3 Lier des événements coulissants
Ajouter un événement coulissant à la barre d'index de droite, qui est déclenché lors d'un clic ou d'un glissement. Dans le code source, à la fin de l'événement touchstart, les événements touchmove et touchend sont liés à la fenêtre afin d'agrandir la zone de glissement. Uniquement lorsque l'événement touchstart est déclenché sur la barre d'index au début, puis sur la barre d'index. window Déclenche des événements de glissement et de fin, ce qui signifie que nous pouvons glisser dans la zone de contenu à gauche pendant le processus de glissement, et en même temps obtenir l'effet d'index.
function handleTouchstart(e) { // 如果不是从索引栏开始滑动,则直接return // 保证了左侧内容区域能够正常滑动 if (e.target.tagName !== 'LI') { return; } // 记录开始的clientX值,这个clientX值将在之后的滑动中持续用到,用于定位 navOffsetX = e.changedTouches[0].clientX; // 内容滑动到指定区域 scrollList(e.changedTouches[0].clientY); if (indicatorTime) { clearTimeout(indicatorTime); } moving = true; // 在window区域注册滑动和结束事件 window.addEventListener('touchmove', handleTouchMove, { passive: false }); window.addEventListener('touchend', handleTouchEnd); }
e.changedTouches est utilisé ici Vous pouvez vérifier cette API sur MDN.
Si le multi-touch n'est pas utilisé, la différence entre les changesTouches et les touches n'est pas particulièrement grande. Si l'on clique sur changesTouches deux fois sur le même point, il n'y aura pas de valeur tactile la deuxième fois. Pour plus de détails, vous pouvez lire cet article
Voyons comment slider :
function scrollList(y) { // 通过当前的y值以及之前记录的clientX值来获得索引栏中的对应item var currentItem = document.elementFromPoint(navOffsetX, y); if (!currentItem || !currentItem.classList.contains('indexlist-navitem')) { return; } // 显示指示器 currentIndicator = currentItem.innerText; indicator.innerText = currentIndicator; indicator.style.display = ''; // 找到左侧内容的对应section var targets = [].slice.call(sections).filter(function(section) { var index = section.getAttribute('data-index'); return index === currentItem.innerText; }); var targetDOM; if (targets.length > 0) { targetDOM = targets[0]; // 通过对比要滑动到的区域的top值与最开始的一个区域的top值 // 两者的差值即为要滚动的距离 content.scrollTop = targetDOM.getBoundingClientRect().top - firstSection.getBoundingClientRect().top; // 或者使用scrollIntoView来达到相同的目的 // 不过存在兼容性的问题 // targetDOM.scrollIntoView(); } }
Pour l'API d'elementFromPoint, vous pouvez lire ici
caniuse Compatibilité de getBoundingClientRect et scrollIntoView sur .com
getBoundingClientRect
scrollIntoView
Enfin nécessaire Désenregistrer l'événement de glissement sur la fenêtre
window.removeEventListener('touchmove', handleTouchMove); window.removeEventListener('touchend', handleTouchEnd);
Résumé
Il y a tellement d'analyses, vous. peut apprendre une excellente conception en examinant le code source pour plus d'idées. Par exemple, si on me demandait de le faire au début, je pourrais uniquement lier les événements à la barre d'index du côté droit et ne pas associer le contenu du côté gauche, de sorte que la zone de glissement serait considérablement réduite.
Vous pouvez acquérir des connaissances relativement lointaines en consultant le code source et vous encourager à apprendre. Par exemple, l'étude des API telles que changesTouches et elementFromPoint dans l'article.
Recommandations associées :
Introduction à l'effet IndexList sur le terminal mobile
js réalise l'effet carrousel coulissant du doigt sur le terminal mobile
Comment déterminer les écrans horizontaux et verticaux en HTML5 mobile
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!