Heim  >  Artikel  >  Web-Frontend  >  So verwenden Sie Swiper auf Mobilgeräten

So verwenden Sie Swiper auf Mobilgeräten

小云云
小云云Original
2018-01-26 13:29:052540Durchsuche

Kürzlich habe ich die Vue-Front-End-Komponentenbibliothek von Ele.me in der mobilen Entwicklung verwendet, da ich sie nicht nur als Komponenten verwenden möchte, sondern ein tieferes Verständnis des Implementierungsprinzips erlangen möchte. Dieser Artikel stellt hauptsächlich die relevanten Informationen von Swiper zu mobilen Effekten vor und hat einen gewissen Referenzwert. Ich hoffe, er kann jedem helfen.

Der Code ist hier: stupse mich an

1. Beschreibung

Übergeordneter Container overflow:hidden;, Unterseitetransform:translateX(-100 %);width:100 %;

2. Kernanalyse

2.1 Seiteninitialisierung

Da alle Seiten eine Bildschirmbreite auf der linken Seite des Handybildschirms haben, ist die Ausgangssituation, dass keine Unterseite in der Seite zu sehen ist, also Der erste Schritt sollte darin bestehen, die Unterseite festzulegen, die angezeigt werden soll, standardmäßig 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 Container-Schiebestart (onTouchStart)

Auf niedrigeren Versionen von Android-Telefonen wird die Einstellung von event.preventDefault() die Leistung bis zu einem gewissen Grad verbessern, wodurch das Gleiten weniger verzögert wird.

Vorarbeit:

  • Wenn der Benutzer „prevent:true“ festlegt, wird das Standardverhalten beim Schieben verhindert

  • Wenn das Benutzersätze verhindern:true Mit stopPropagation:true verhindern Sie, dass sich das Ereignis beim Gleiten nach oben ausbreitet

  • Wenn die Animation noch nicht beendet ist, verhindern Sie das Gleiten

  • Ziehen einstellen:true und das Schieben beginnt

  • Benutzer-Scrolling auf false setzen

Swipe-Start:

Verwenden Sie ein globales Objekt, um Informationen aufzuzeichnen. Zu diesen Informationen gehören:


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

2.3 Container Slide (onTouchMove)

Global anwenden dragState und neue Informationen aufzeichnen


dragState = {
  currentLeft     // 开始的X坐标
  currentTop     // 开始的Y坐标(相对于整个页面viewport pageY)
  currentTopAbsolute // 绝对Y坐标(相对于文档顶部 clientY)
};

Dann können wir aus den Informationen in Start und Slide etwas berechnen:

Horizontale Verschiebung des Slides (offsetLeft = currentLeft - startLeft)

Die vertikale Verschiebung der Folie (offsetTop = currentTopAbsolute - startTopAbsolute)

Ist es das natürliche Scrollen des Benutzers? Das natürliche Scrollen hier bedeutet, dass der Benutzer die Folie nicht verschieben möchte Swiper, möchte aber die Seite verschieben


// 条件
// distanceX = Math.abs(offsetLeft);
// distanceY = Math.abs(offsetTop);
distanceX < 5 || ( distanceY >= 5 && distanceY >= 1.73 * distanceX )

Bestimmen Sie, ob nach links oder rechts verschoben werden soll (offsetLeft < 0, nach links verschieben, andernfalls nach rechts verschieben)

Verschiebung zurücksetzen


// 如果存在上一个页面并且是左移
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 Gleitende (onTouchEnd)

Vorarbeit:

Während des Gleitens können wir Beurteilen Sie in Echtzeit, ob es für den Benutzer natürlich ist. Scrollen durch den Benutzer. Wenn der Benutzer auf natürliche Weise scrollt, zählen die Gleitinformationen von Swiper nicht, daher müssen einige Löschvorgänge durchgeführt werden:


dragging = false;
dragState = {};

Natürlich Wenn userScrolling:false, dann ist es, die Unterseite zu verschieben und die doOnTouchEnd-Methode

auszuführen, um festzustellen, ob dies der Fall ist ein Tap-Event


// 时间小于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;);
  }
}

Richterrichtung


// 如果事件间隔小于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;
}

Animation ausführen


// 当没有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);
}

Nacharbeit:

Löschen Sie die in einem Gleitzyklus gespeicherten Statusinformationen


dragging = false;
dragState = {};

Zusammenfassung

Gesamt Das Implementierungsprinzip ist relativ einfach. Wischen Sie, um die Anfangsposition aufzuzeichnen und die vorherige und nächste Seite zu berechnen Die nächste Seite wird berechnet. Am Ende des Schiebevorgangs wird die entsprechende Animation basierend auf dem Verschiebungsergebnis ausgeführt.

Ein Detail besteht darin, dass der Effekt des Übergangs auf „leer“ gesetzt ist, um zu verhindern, dass sich die vorherige und nächste Seite aufgrund des Übergangs unnatürlich verschieben Folie ist vorbei.

Verwandte Empfehlungen:

Realisierung der kombinierten Wirkung von WeChat Mini-Programm-Tab und Swiper

Detaillierte Erklärung des Vue-Swipers Umsetzung der Komponentenentwicklung

Ausführliche Erklärung zur Verwendung von Swiper

Das obige ist der detaillierte Inhalt vonSo verwenden Sie Swiper auf Mobilgeräten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn