Heim >Web-Frontend >js-Tutorial >So implementieren Sie eine seitlich verschiebbare Menükomponente in Vue

So implementieren Sie eine seitlich verschiebbare Menükomponente in Vue

亚连
亚连Original
2018-06-20 10:45:053880Durchsuche

In diesem Artikel wird die Implementierung einer einfachen DrawerLayout-Layoutkomponente (ähnlich der DrawerLayout-Komponente von Android) vorgestellt.

Dieser Artikel führt ein einfaches DrawerLayout ein ( Implementierung von Layoutkomponenten ähnlich dem DrawerLayout von Android, basierend auf Vue.js. Der eingeführte Inhalt wurde in die Vue-Drawer-Layout-Komponente umgewandelt.

Vorwort

Bei Interesse scannen Sie bitte zuerst diesen QR-Code mit Ihrem Handy, oder klicken Sie auf mich

und klicken Sie dann auf „Schublade öffnen“ oder ziehen Sie den Avatar in der oberen linken Ecke der Seite nach rechts oder links, und Sie können den Effekt des GIF unten sehen. Sehen Sie nicht so aus? :)

Google nennt dieses Layout offiziell DrawerLayout (Schubladennavigationsleiste). Wie erreichen wir das? Beginnen wir mit dem Hauptfilm!

HTML-Struktur

Die Seitenstruktur ist sehr einfach, mit einer Schublade und einem Hauptcontainer, und der Inhalt kann über Slots extern angepasst werden .

<p class="drawer-layout">
  <!--抽屉-->
  <p class="drawer-wrap">
    <slot name="drawer"></slot>
  </p>
  <!--主容器-->
  <p class="content-wrap">
    <!--遮罩-->
    <p class="drawer-mask"></p>
    <slot name="content"></slot>
  </p>
</p>

Die Schublade ist zunächst außerhalb des linken Bildschirms ausgeblendet. Stellen Sie also links: -100 % ein, um sie vollständig außerhalb auszublenden.

Benutzen Sie Touch

Bestimmen Sie zunächst, ob der Browser touchEvent unterstützt

let isTouch = &#39;ontouchstart&#39; in window;
  let mouseEvents = isTouch ?
    {
      down: &#39;touchstart&#39;,
      move: &#39;touchmove&#39;,
      up: &#39;touchend&#39;,
      over: &#39;touchstart&#39;,
      out: &#39;touchend&#39;
    } :
    {
      down: &#39;mousedown&#39;,
      move: &#39;mousemove&#39;,
      up: &#39;mouseup&#39;,
      over: &#39;mouseover&#39;,
      out: &#39;mouseout&#39;
    };

Touchdown-Ereignis binden

document.addEventListener(mouseEvents.down, initDrag, false);

Definieren Sie zunächst eine Variable, das x -Koordinate des gedrückten Fingers wird als startX markiert, die x-Koordinate des Fingers während des Gleitens wird als nowX markiert und der x-Koordinatenversatz der Schublade wird als startPos markiert

let startX, nowX, startPos;

Wenn Touchstart ausgelöst wird, Die Startposition wird aufgezeichnet und gebunden. Bestimmen Sie touchmove. Hinweis: Wenn es sich um ein MouseEvent handelt, wird die aktuelle X-Koordinate über e.clientX abgerufen. Wenn es sich um ein TouchEvent handelt, wird die X-Koordinate über e.changedTouches[0].clientX

const initDrag = function (e) {
  startX = e.clientX || e.changedTouches[0].clientX; //记录手指按下的位置
  startPos = this.pos; //记录drawer的上次位置
  document.addEventListener(mouseEvents.move, drag, false);
  document.addEventListener(mouseEvents.up, removeDrag, false);
}.bind(this);
const drag = function (e) {
  nowX = e.clientX || e.changedTouches[0].clientX; //滑动中手指的位置x坐标
  let pos = startPos + nowX - startX; 
  pos = Math.min(width, pos); //不能超过滑动最大值
  pos = Math.max(0, pos); //不能小于0
  this.pos = pos; //设置滚动距离为拖动的距离
}.bind(this);

Dann gleitet der Finger um den Abstand nowX - startX und die aktuelle Schubladenposition ist startPos + nowX - startX, sodass die Schublade dem Finger gefolgt ist, um sich nach rechts zu bewegen, und das Maximum nicht überschreitet Widerstandswert, den wir festlegen.

Unterscheiden Sie zwischen vertikalem und horizontalem Gleiten

Als nächstes werden Sie ein Problem finden: Wenn Ihr Finger den Hauptinhalt vertikal scrollt, schieben Sie Ihren Finger nach rechts Es wird auch die Schublade herausziehen. Zu diesem Zeitpunkt sollten Sie eines tun: zwischen vertikalem Gleiten und horizontalem Gleiten unterscheiden

Natürlich gibt es viele Möglichkeiten, die trigonometrische Funktionen verwenden zu bestimmen

Angenommen, jeder Pfeil im obigen Bild ist die Richtung, in die der Finger gleitet. Der grüne Pfeil bedeutet, dass die Schublade herausgezogen werden kann, und der rote Pfeil bedeutet dass es nicht herausgezogen werden kann (beachten Sie, dass der rote Pfeil auch den Versatz der x-Koordinate hat). Das heißt, wenn die Schublade nicht herausgezogen werden kann, sollten Standardereignisse wie vertikales Scrollen usw. ausgelöst werden.

Wenn der Finger drückt, um Touchstart auszulösen, wird die Anfangsposition P 0 aufgezeichnet. Wenn der Finger gleitet, wird die erste Touchmove ausgelöst, die Position P 1 wird aufgezeichnet und wir zeichnen den Vektor von P 0 bis auf P 1 als S (Verzeihen Sie mir, dass ich ein Seelenmaler bin)

Zu diesem Zeitpunkt ist es leicht zu erkennen, dass ∠θ größer als ein bestimmter Wert ist, beispielsweise 30 Grad kann es sich um einen vertikalen Bildlauf handeln, anstatt die Schublade zu ziehen. Daher kann die Beurteilungsbedingung basierend auf y/x>tan30°

erhalten werden:

if (isVerticle === undefined) isVerticle = Math.abs(nowY - startY) / Math.abs(nowX - startX) > (Math.sqrt(3) / 3);

Wenn isVerticle wahr ist, wird das Ziehen der Schublade nicht durchgeführt

Lassen Sie die Schubladenbewegung

Wir verwenden das Übergangsattribut von CSS3, um der Schublade einen Übergangsanimationseffekt zu verleihen

.moving
  transition transform .3s ease

Vergessen Sie nicht, eine Klassenbindung hinzuzufügen Beim Ziehen ist eine Übergangsanimation erforderlich (erforderlich: Folgen Sie Ihrem Finger), und die Übergangsanimation ist nur erforderlich, wenn Sie Ihren Finger loslassen.

<p class="drawer-wrap" :class="{&#39;moving&#39;:moving,&#39;will-change&#39;:willChange}"
   :style="{width:`${width}px`,left:`-${width)}px`,transform:`translate3d(${pos}px,0,0)`}">
  <slot name="drawer"></slot>
</p>

Wenn Sie also die Touchend-Ereignismethode binden, müssen Sie diese Schritte ausführen

const removeDrag = function (e) {
  if (isVerticle !== undefined) {
    if (!isVerticle) {//当判定为抽屉拖动才进入
      let pos = this.pos;
      this.visible = pos > width * 3 / 5 //当前位置如果大于总宽度的3/5就判定为全部展开抽屉,否则将抽屉弹回隐藏
      if (this.pos > 0 && this.pos < width) this.moving = true;//如果位置已经处于最小值或最大值处,不需要有动画效果了
    }
    this.pos = this.visible ? width : 0;
  }
  if (!this.moving) {
    this.willChange = false; //留个悬念
  }
  isVerticle = undefined;
  //取消touchmove和touchend事件绑定
  document.removeEventListener(mouseEvents.move, drag, false);
  document.removeEventListener(mouseEvents.up, removeDrag, false);
}.bind(this);

Sie finden dies.willChange = false im obigen Code. Was bewirkt es? Im Folgenden fragen wir nach der Will-Change-Methode von CSS

.will-change

Will-Change-Transformation

Das CSS-Attribut Will-Change bietet Webentwicklern eine Möglichkeit, dem Browser dies mitzuteilen Wie sich die Elemente ändern, damit der Browser im Vorfeld entsprechende Optimierungsvorbereitungen treffen kann, bevor sich die Elementattribute tatsächlich ändern. Diese Art der Optimierung kann einen Teil der komplexen Berechnungsarbeit im Voraus vorbereiten und die Seitenreaktion schneller und empfindlicher machen.

Tatsächlich können wir die Browser-Schublade im Voraus darüber informieren, dass die Browser-Schublade möglicherweise in Touchstart verschoben wird

const initDrag = function (e) {
  //...
  this.willChange = true;
}.bind(this);

Vergessen Sie natürlich nicht, den Übergang zu entfernen und den Willen zu ändern Transitionend-Ereignis und lassen Sie den Browser eine Weile ruhen ~

Was kann noch optimiert werden?

Die oben genannten Hauptfunktionen sind grundsätzlich implementiert, aber gibt es noch etwas, das optimiert werden kann?

Hä? Was zum Teufel ist passiv

?

网站使用被动事件侦听器以提升滚动性能,在您的触摸和滚轮事件侦听器上设置 passive 选项可提升滚动性能具体看这里

原来这是现代浏览器的一个新特性,我们需要以新的方式来绑定我们的touch事件,当然首先先检测一下是否支持 passive

const supportsPassive = (() => {
  let supportsPassive = false;
  try {
    const opts = Object.defineProperty({}, &#39;passive&#39;, {
      get: function () {
        supportsPassive = true;
      }
    });
    window.addEventListener("test", null, opts);
  } catch (e) {
  }
  return supportsPassive;
})();

于是我们的绑定事件代码变成这样

document.addEventListener(mouseEvents.move, drag, supportsPassive ? {passive: true} : false);

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

Bootstrap栅格系统(详细教程)

在jQuery中如何实现点击DIV触发点击CheckBox

在React Native中使用prop-types如何实现属性确认

在jQuery中如何实现弹窗下底部页面禁止滑动效果

$refs访问Vue中的DOM(详细教程)

Das obige ist der detaillierte Inhalt vonSo implementieren Sie eine seitlich verschiebbare Menükomponente in Vue. 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