Home > Web Front-end > JS Tutorial > Detailed explanation of IndexList on mobile terminal

Detailed explanation of IndexList on mobile terminal

小云云
Release: 2018-01-04 14:06:42
Original
1735 people have browsed it

This article mainly introduces the IndexList of mobile terminal effects in detail. It has certain reference value. Interested friends can refer to it. I hope it can help everyone.

Written in front

Following the previous mobile effects talk, this time I will explain the implementation principle of IndexList. The effect is as follows:

Please see the code here: github

Swiper for mobile effects

Picker for mobile effects

Mobile terminal effect of cellSwiper

1. Core analysis

The overall principle is that when you click or slide the index bar on the right, by getting Click the index value to slide the content on the left to the corresponding position. How to slide to a specific position, see the breakdown below:

1.1 Basic html code


<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>
Copy after login

1.2 DOM initialization

Because I’m hungry The indexList in the component library uses the vue component to generate DOM. I roughly use javascript to simulate the DOM generation here.


// 内容填充
function initialDOM() {
 // D.data 获取内容数据
 var data = D.data;
 var contentHtml = &#39;&#39;;
 var navHtml = &#39;&#39;;
 // 初始化内容和NAV
 data.forEach(function(d) {
  var index = d.index;
  var items = d.items;
  navHtml += &#39;<li class="indexlist-navitem">&#39;+ index +&#39;</li>&#39;;
  contentHtml += &#39;<li class="indexsection" data-index="&#39;+ index +&#39;"><p class="indexsection-index">&#39;+ index +&#39;</p><ul>&#39;;
  items.forEach(function(item) {
   contentHtml += &#39;<a class="cell"><p class="cell-wrapper"><p class="cell-title"><span class="cell-text">&#39;+ item +&#39;</span></p></p></a>&#39;;
  });
  contentHtml += &#39;</ul></li>&#39;;
 });

 content.innerHTML = contentHtml;
 navList.innerHTML = navHtml;
}

// 样式初始化
if (!currentHeight) {
 currentHeight = document.documentElement.clientHeight -content.getBoundingClientRect().top;
}
// 右边索引栏的宽度
navWidth = nav.clientWidth;
// 左边内容的初始化高度和右边距
// 高度为当前页面的高度与内容top的差值
content.style.marginRight = navWidth + &#39;px&#39;;
content.style.height = currentHeight + &#39;px&#39;;
Copy after login

1.3 Bind sliding event

Add a sliding event to the index bar on the right, which is triggered when clicking or sliding. In the source code, at the end of the touchstart event, the touchmove and touchend events are bound to the window in order to make the sliding area larger. Only when the touchstart event is triggered on the index bar at the beginning, then on the window Trigger sliding and end events, which means that we can slide in the content area on the left during the sliding process, and at the same time achieve the index effect.


function handleTouchstart(e) {
 // 如果不是从索引栏开始滑动,则直接return
 // 保证了左侧内容区域能够正常滑动
 if (e.target.tagName !== &#39;LI&#39;) {
  return;
 }
 
 // 记录开始的clientX值,这个clientX值将在之后的滑动中持续用到,用于定位
 navOffsetX = e.changedTouches[0].clientX;
 
 // 内容滑动到指定区域
 scrollList(e.changedTouches[0].clientY);
 if (indicatorTime) {
  clearTimeout(indicatorTime);
 }
 moving = true;
 
 // 在window区域注册滑动和结束事件
 window.addEventListener(&#39;touchmove&#39;, handleTouchMove, { passive: false });
 window.addEventListener(&#39;touchend&#39;, handleTouchEnd);
}
Copy after login

e.changedTouches is used here. You can check this API on MDN.

If multi-touch is not used, the difference between changedTouches and touches is not particularly big. If changedTouches is clicked twice on the same point, there will be no touch value the second time. For details, you can read this article

Let’s take a look at how to slide:


function scrollList(y) {
 // 通过当前的y值以及之前记录的clientX值来获得索引栏中的对应item
 var currentItem = document.elementFromPoint(navOffsetX, y);
 if (!currentItem || !currentItem.classList.contains(&#39;indexlist-navitem&#39;)) {
  return;
 }
 
 // 显示指示器
 currentIndicator = currentItem.innerText;
 indicator.innerText = currentIndicator;
 indicator.style.display = &#39;&#39;;

 // 找到左侧内容的对应section
 var targets = [].slice.call(sections).filter(function(section) { 
  var index = section.getAttribute(&#39;data-index&#39;);
  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();
 }
}
Copy after login

For the API of elementFromPoint, you can see here

caniuse.com About the compatibility of getBoundingClientRect and scrollIntoView

getBoundingClientRect

##scrollIntoView

Finally, you need to log out of the window Sliding event on


window.removeEventListener(&#39;touchmove&#39;, handleTouchMove);
window.removeEventListener(&#39;touchend&#39;, handleTouchEnd);
Copy after login

2. Summary
So much for analysis, you can learn excellent design concepts by looking more at the source code. For example, if I were asked to do it at the beginning, I could only bind the event to the index bar on the right and not associate the content on the left, so that the sliding area will be greatly reduced.

At the same time, you can learn some relatively remote knowledge by looking at the source code and encourage yourself to learn. For example, the study of APIs such as changedTouches and elementFromPoint in the article.

Related recommendations:


Introduction to the IndexList effect on the mobile terminal

js realizes the finger sliding carousel effect on the mobile terminal

How to determine horizontal and vertical screens in mobile HTML5

The above is the detailed content of Detailed explanation of IndexList on mobile terminal. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template