Maison  >  Article  >  interface Web  >  Comment utiliser Swiper sur mobile

Comment utiliser Swiper sur mobile

小云云
小云云original
2018-01-26 13:29:052539parcourir

Récemment, j'ai utilisé la bibliothèque de composants front-end vue d'Ele.me dans le développement mobile. Parce que je ne veux pas l'utiliser simplement comme composants, je souhaite mieux comprendre le principe d'implémentation. Cet article présente principalement en détail les informations pertinentes de Swiper sur les effets mobiles. Il a une certaine valeur de référence. Les amis intéressés peuvent s'y référer.

Le code est ici : poke me

1 Description

Conteneur parent overflow:hidden;, Sous-pagetransform:translateX(-100%);width:100%;

Analyse de base

2.1 Initialisation de la page

Étant donné que toutes les pages font une largeur d'écran sur le côté gauche de l'écran du téléphone mobile, la situation initiale est qu'aucune sous-page ne peut être vue dans la page, donc la première étape doit être Définir la sous-page qui doit être affichée, par défaut

defaultIndex:0


function reInitPages() {
  // 得出页面是否能够被滑动
  // 1. 子页面只有一个
  // 2. 用户手动设置不能滑动 noDragWhenSingle = true
  noDrag = children.length === 1 && noDragWhenSingle;

  var aPages = [];
  var intDefaultIndex = Math.floor(defaultIndex);
  var defaultIndex = (intDefaultIndex >= 0 && intDefaultIndex < children.length) 
    ? intDefaultIndex : 0;
  
  // 得到当前被激活的子页面索引
  index = defaultIndex;

  children.forEach(function(child, index) {
    aPages.push(child);
    // 所有页面移除激活class
    child.classList.remove(&#39;is-active&#39;);

    if (index === defaultIndex) {
      // 给激活的子页面加上激活class
      child.classList.add(&#39;is-active&#39;);
    }
  });

  pages = aPages;
}
2.2 Démarrage coulissant du conteneur (onTouchStart)

Sur les versions inférieures des téléphones

android, la configuration de event.preventDefault() améliorera les performances dans une certaine mesure, rendant le glissement moins lent.

Pré-travail :

  • Si l'utilisateur définit Prevent:true, empêche le comportement par défaut lors du glissement

  • Si le l'utilisateur définit Prevent:true Avec stopPropagation:true, empêche l'événement de se propager vers le haut lors du glissement

  • Si l'animation n'est pas encore terminée, empêche le glissement

  • Définissez le glissement : vrai et le début du glissement

  • Définissez le défilement de l'utilisateur sur faux


Démarrage par balayage :

Utilisez un objet global pour enregistrer des informations, notamment :


dragState = {
  startTime      // 开始时间
  startLeft      // 开始的X坐标
  startTop      // 开始的Y坐标(相对于整个页面viewport pageY)
  startTopAbsolute  // 绝对Y坐标(相对于文档顶部 clientY)
  pageWidth      // 一个页面宽度
  pageHeight     // 一个页面的高度
  prevPage      // 上一个页面
  dragPage      // 当前页面
  nextPage      // 下一个页面
};
2.3 Container Slide (onTouchMove)

Apply global

dragState et enregistrer de nouvelles informations


dragState = {
  currentLeft     // 开始的X坐标
  currentTop     // 开始的Y坐标(相对于整个页面viewport pageY)
  currentTopAbsolute // 绝对Y坐标(相对于文档顶部 clientY)
};
Ensuite, nous pouvons calculer quelque chose à partir des informations du début et de la diapositive :

Déplacement horizontal de la diapositive (offsetLeft = currentLeft - startLeft)

Le déplacement vertical de la diapositive (offsetTop = currentTopAbsolute - startTopAbsolute)

Est-ce le défilement naturel de l'utilisateur ? Le défilement naturel signifie ici que l'utilisateur ne veut pas faire glisser le curseur ? swiper, mais veut faire glisser la page


// 条件
// distanceX = Math.abs(offsetLeft);
// distanceY = Math.abs(offsetTop);
distanceX < 5 || ( distanceY >= 5 && distanceY >= 1.73 * distanceX )
Déterminer s'il faut se déplacer à gauche ou à droite (offsetLeft < 0, se déplacer à gauche, sinon, se déplacer à droite)

Réinitialiser le déplacement


// 如果存在上一个页面并且是左移
if (dragState.prevPage && towards === &#39;prev&#39;) {
  // 重置上一个页面的水平位移为 offsetLeft - dragState.pageWidth
  // 由于 offsetLeft 一直在变化,并且 >0
  // 那么也就是说 offsetLeft - dragState.pageWidth 的值一直在变大,但是仍未负数
  // 这就是为什么当连续属性存在的时候左滑会看到上一个页面会跟着滑动的原因
  // 这里的 translate 方法其实很简单,在滑动的时候去除了动画效果`transition`,单纯改变位移
  // 而在滑动结束的时候,加上`transition`,使得滑动到最后释放的过渡更加自然
  translate(dragState.prevPage, offsetLeft - dragState.pageWidth);
}

// 当前页面跟着滑动
translate(dragState.dragPage, offsetLeft);

// 后一个页面同理
if (dragState.nextPage && towards === &#39;next&#39;) {
  translate(dragState.nextPage, offsetLeft + dragState.pageWidth);
}
2.4 Extrémité coulissante (onTouchEnd)

Pré-travail :

Pendant le glissement, nous pouvons juger en temps réel s'il est naturel pour l'utilisateur Scroll userScrolling, si l'utilisateur scrolle naturellement, alors les informations de glissement du

swiper ne comptent pas, donc quelques opérations d'effacement doivent être effectuées :


dragging = false;
dragState = {};
Bien sûr Si userScrolling:false, alors c'est une sous-page coulissante, exécutez la méthode doOnTouchEnd

pour déterminer s'il s'agit d'une événement de claquettes


// 时间小于300ms,click事件延迟300ms触发
// 水平位移和垂直位移栋小于5像素
if (dragDuration < 300) {
  var fireTap = Math.abs(offsetLeft) < 5 && Math.abs(offsetTop < 5);
  if (isNaN(offsetLeft) || isNaN(offsetTop)) {
    fireTap = true;
  }
  if (fireTap) {
    console.log(&#39;tap&#39;);
  }
}

Direction du juge


// 如果事件间隔小于300ms但是滑出屏幕,直接返回
if (dragDuration < 300 && dragState.currentLeft === undefined) return;

// 如果事件间隔小于300ms 或者 滑动位移超过屏幕宽度 1/2, 根据位移判断方向
if (dragDuration < 300 || Math.abs(offsetLeft) > pageWidth / 2) {
  towards = offsetLeft < 0 ? &#39;next&#39; : &#39;prev&#39;;
}

// 如果非连续,当处于第一页,不会出现上一页,当处于最后一页,不会出现下一页
if (!continuous) {
  if ((index === 0 && towards === &#39;prev&#39;) 
    || (index === pageCount - 1 && towards === &#39;next&#39;)) {
    towards = null;
  }
}

// 子页面数量小于2时,不执行滑动动画
if (children.length < 2) {
  towards = null;
}

Exécuter l'animation


// 当没有options的时候,为自然滑动,也就是定时器滑动
function doAnimate(towards, options) {
  if (children.length === 0) return;
  if (!options && children.length < 2) return;

  var prevPage, nextPage, currentPage, pageWidth, offsetLeft;
  var pageCount = pages.length;

  // 定时器滑动
  if (!options) {
    pageWidth = element.clientWidth;
    currentPage = pages[index];
    prevPage = pages[index - 1];
    nextPage = pages[index + 1];
    if (continuous && pages.length > 1) {
      if (!prevPage) {
        prevPage = pages[pages.length - 1];
      }

      if (!nextPage) {
        nextPage = pages[0];
      }
    }

    // 计算上一页与下一页之后
    // 重置位移
    // 参看doOnTouchMove
    // 其实这里的options 传与不传也就是获取上一页信息与下一页信息
    if (prevPage) {
      prevPage.style.display = &#39;block&#39;;
      translate(prevPage, -pageWidth);
    }

    if (nextPage) {
      nextPage.style.display = &#39;block&#39;;
      translate(nextPage, pageWidth);
    }
  } else {
    prevPage = options.prevPage;
    currentPage = options.currentPage;
    nextPage = options.nextPage;
    pageWidth = options.pageWidth;
    offsetLeft = options.offsetLeft;
  }

  var newIndex;
  var oldPage = children[index];

  // 得到滑动之后的新的索引
  if (towards === &#39;prev&#39;) {
    if (index > 0) {
      newIndex = index - 1;
    }
    if (continuous && index === 0) {
      newIndex = pageCount - 1;
    }
  } else if (towards === &#39;next&#39;) {
    if (index < pageCount - 1) {
      newIndex = index + 1;
    }
    if (continuous && index === pageCount - 1) {
      newIndex = 0;
    }
  }

  // 动画完成之后的回调
  var callback = function() {
    // 得到滑动之后的激活页面,添加激活class
    // 重新赋值索引
    if (newIndex !== undefined) {
      var newPage = children[newIndex];
      oldPage.classList.remove(&#39;is-active&#39;);
      newPage.classList.add(&#39;is-active&#39;);
      index = newIndex
    }

    if (isDone) {
      end();
    }

    if (prevPage) {
      prevPage.style.display = &#39;&#39;;
    }

    if (nextPage) {
      nextPage.style.display = &#39;&#39;;
    }
  }

  setTimeout(function() {
    // 向后滑动
    if (towards === &#39;next&#39;) {
      isDone = true;
      before(currentPage);
      // 当前页执行动画,完成后执行callback
      translate(currentPage, -pageWidth, speed, callback);
      if (nextPage) {
        // 下一面移动视野中
        translate(nextPage, 0, speed)
      }
    } else if (towards === &#39;prev&#39;) {
      isDone = true;
      before(currentPage);
      translate(currentPage, pageWidth, speed, callback);
      if (prevPage) {
        translate(prevPage, 0, speed);
      }
    } else {
     // 如果既不是左滑也不是右滑
     isDone = true;
     // 当前页面依旧处于视野中
     // 上一页和下一页滑出
     translate(currentPage, 0, speed, callback);
     if (typeof offsetLeft !== &#39;undefined&#39;) {
       if (prevPage && offsetLeft > 0) {
          translate(prevPage, pageWidth * -1, speed);
       }
       if (nextPage && offsetLeft < 0) {
          translate(nextPage, pageWidth, speed);
       }
     } else {
      if (prevPage) {
       translate(prevPage, pageWidth * -1, speed);
      }

      if (nextPage) {
       translate(nextPage, pageWidth, speed);
      }
     }
    }
  }, 10);
}

Publier le travail :

Effacer les informations d'état enregistrées dans un cycle glissant


dragging = false;
dragState = {};

Résumé

Dans l'ensemble, le principe de mise en œuvre est relativement simple. Glissez pour commencer à enregistrer la position initiale, et calculez les pages précédentes et suivantes. La page qui doit être affichée sur une page est calculée lors du glissement, ainsi que le déplacement de la page précédente et de la suivante. la page est calculée ; à la fin du glissement, l'animation correspondante est exécutée en fonction du résultat du déplacement.

Un détail est que lors du glissement, l'effet de

transition est défini sur vide pour éviter que la page précédente et la page suivante ne se décalent anormalement en raison de la transition. Ajoutez-leur des effets d'animation après la transition. la diapositive est terminée.

Recommandations associées :


Réalisation de l'effet combiné de l'onglet et du swiper de l'applet WeChat

Explication détaillée de la mise en œuvre de la vue swiper du développement de composants

Explication détaillée de la façon d'utiliser swiper

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn