Heim > Web-Frontend > js-Tutorial > Hauptteil

Virtuelle Bildlaufleisten etwa 2.x in vue.js

亚连
Freigeben: 2018-06-09 17:25:55
Original
1520 Leute haben es durchsucht

In diesem Artikel wird hauptsächlich der Beispielcode der virtuellen Bildlaufleiste basierend auf vue.js 2.x vorgestellt. Jetzt teile ich ihn mit Ihnen und gebe ihn als Referenz.

Vorwort

Ich erinnere mich, dass ich zuvor zufällig ein Open-Source-CMS-Projekt durchgesehen habe und festgestellt habe, dass das linke Menü dieses Projekts die Breite der Fenster überschreitet. Ich war neugierig, warum. Es gibt keine Bildlaufleiste? Dann habe ich genauer hingesehen und auf der linken Seite ein kleines p gefunden. Dann habe ich versucht, es zu ziehen, und festgestellt, dass es mit der nativen Bildlaufleiste identisch ist! Als ich mir den Quellcode ansah, entdeckte ich, dass diese Bildlaufleiste „slimScroll“ heißt. Dann ging ich zu ihrem Github-Repository und schaute sie mir an. Nachdem ich den Quellcode studiert hatte, hatte ich das Gefühl, dass ich die gleiche Bildlaufleiste auch erstellen könnte. Erreicht durch Vue!

Design

Okay, jetzt beginnen wir mit den Schritten zum Entwerfen der Bildlaufleiste:

Dom der Bildlaufleiste entwerfen

Das erste, woran Sie denken müssen, ist: Wenn Sie den Inhalt scrollen möchten, den Sie scrollen möchten, muss der übergeordnete Dom zunächst eine feste Länge und Breite haben, dh der überschüssige Teil muss ausgeblendet sein. Das heißt, fügen Sie einen Stil hinzu: Overflow: Hidden. Daher fügen wir dem zu scrollenden Inhalt einen Wrapper hinzu, sodass seine Länge und Breite dem übergeordneten Dom entsprechen, und dann gibt es einen Stil namens: Overflow: Hidden und den Das umschlossene Element heißt scrollPanel

Zweitens: Wir wissen: Wir wollen es so leistungsstark machen wie die native Bildlaufleiste! Es ist notwendig, horizontale Bildlaufleisten und vertikale Bildlaufleisten zu entwerfen, die zur Beziehung zwischen Geschwisterknoten gehören, da das Vorhandensein der Bildlaufleiste den ursprünglichen Stil nicht beeinträchtigen kann und die Position oben und links steuert , also die Bildlaufleiste Die Position muss absolut sein. Nun, wir nennen die horizontale Bildlaufleiste: hBar und die vertikale Bildlaufleiste: vBar

Schließlich: Wir haben scrollPanel, vBar, hBar entworfen und brauchen ein übergeordnetes Element p, um sie einzuwickeln, und fügen Sie dann einen Stil hinzu: Position: relativ

Üben

Komponentenstruktur entwerfen

Zuerst Alles in allem bestehen unsere Plug-Ins aus 4 Komponenten, von denen 3 untergeordnete Komponenten und 1 eine übergeordnete Komponente sind, nämlich: vueScroll (übergeordnete Komponente), scrollPanel (Unterkomponente, die Inhalte umschließt, die gescrollt werden müssen), vBar (vertikale Bildlaufleiste) , hBar (horizontale Bildlaufleiste)

Zweitens entwerfen wir die Funktionen, für die jede Komponente verantwortlich ist. Die Komponenten sind hier in Komponenten der Steuerungsschicht und Komponenten der Anzeige unterteilt (Studenten, die mit React vertraut sind, sollten dies wissen. Die Komponenten der Anzeigeebene vervollständigen nur die Anzeigefunktion: vBar, hBar, scrollPanel Die Komponenten der Steuerungsebene ähneln in gewisser Weise der CPU und können steuern Unterkomponenten. Verschiedene Zustände, wie Breite, Höhe, Farbe, Transparenz, Position usw. Die Steuerungsschichtkomponente ist: vueScroll.

Spezifische Implementierung

hBar/vBar

hBar/vBar Diese beiden sind horizontale Bildlaufleiste bzw. vertikale Bildlaufleiste. Die implementierten Funktionen sind ungefähr gleich, daher werden die alten zusammen erwähnt. Hier nehmen wir vBar als Beispiel.

props empfängt die von der übergeordneten Komponente übergebenen Eigenschaften, insbesondere:

{
  height: vm.state.height + 'px', //滚动条的高度
  width: vm.ops.width, // 滚动条的宽度
  position: 'absolute', 
  background: vm.ops.background, // 滚动条背景色
  top: vm.state.top + 'px', // 滚动条的高度
  transition: 'opacity .5s', // 消失/显示 所用的时间
  cursor: 'pointer', //
  opacity: vm.state.opacity, // 透明度
  userSelect: 'none' 
 }
Nach dem Login kopieren

2-Ereignis, das hauptsächlich die Bildlaufleiste anzeigt, wenn sich die Maus bewegt.

...
render(_c){
  return _c(
    // ...
    {
      mouseenter: function(e) {
        vm.$emit('showVBar'); // 触发父组件事件,显示滚动条
      }
    }
    // ...
  )
}
Nach dem Login kopieren

Dabei stellt state den Zustand dar, der zur Laufzeit geändert werden kann, und ops ist der Konfigurationsparameter, der vom Benutzer übergeben wird.

scrollPanel

ist eine Komponente, die scrollende Inhalte umschließt. Der Stil muss auf „overflow: versteckt“ eingestellt sein.

1. Stil

var style = vm.scrollContentStyle;
 style.overflow = 'hidden';
 // ...
 {
   style: style
 }
 // ...
Nach dem Login kopieren

2. Ereignis

// ...
  render(_c) {
    // ...
      on: {
        mouseenter: function() {
          vm.$emit('showBar');
        },
        mouseleave: function() {
          vm.$emit('hideBar');
        }
      }
    // ...
  }
 // ...
Nach dem Login kopieren

vuescroll

Steuerungskomponente. Steuern Sie den von Unterkomponenten angezeigten Status, fügen Sie verschiedene Abhörereignisse hinzu usw.

1. Rufen Sie das Dom-Element der Unterkomponente ab, um Echtzeitinformationen über den Dom zu erhalten.

// ...
   initEl() {
    this.scrollPanel.el = this.$refs['vueScrollPanel'] && this.$refs['vueScrollPanel'].$el;
    this.vScrollBar.el = this.$refs['vScrollBar'] && this.$refs['vScrollBar'].$el;
    this.hScrollBar.el = this.$refs['hScrollBar'] && this.$refs['hScrollBar'].$el;
  }
  // ...
Nach dem Login kopieren

2. Bildlaufleiste anzeigen

Anzeige der horizontalen Bildlaufleiste und Anzeige der vertikalen Bildlaufleiste als Beispiel:

// ...
    var temp;
    var deltaY = {
      deltaY: this.vScrollBar.ops.deltaY // 获取用户配置的deltaY
    };
    if(!this.isMouseLeavePanel || this.vScrollBar.ops.keepShow){
      if ((this.vScrollBar.state.height = temp = this.getVBarHeight(deltaY))) { // 判断条件
        // 重新设置滚动条的状态
        this.vScrollBar.state.top = this.resizeVBarTop(temp);
        this.vScrollBar.state.height = temp.height;
        this.vScrollBar.state.opacity = this.vScrollBar.ops.opacity;
      }
    }
  // ...
Nach dem Login kopieren

3 , Ermitteln Sie die Höhe der Bildlaufleiste

Da die Höhe des Dom-Elements nicht festgelegt ist, müssen Sie die tatsächliche Höhe des Doms in Echtzeit ermitteln. Die Berechnungsformel für die Höhe des Bildlaufs Die Leiste lautet wie folgt:

var height = Math.max(
      scrollPanelHeight / 
      (scrollPanelScrollHeight / scrollPanelHeight), 
      this.vScrollBar.minBarHeight
      );
Nach dem Login kopieren

Das heißt: scroll Bar height: scrollPanel height == scrollPanel height: dom element height

4. resizeVBarTop, um Fehler zu vermeiden und die Höhe ermitteln zu können der Bildlaufleiste vom übergeordneten Element.

resizeVBarTop({height, scrollPanelHeight, scrollPanelScrollHeight, deltaY}) {
  // cacl the last height first
  var lastHeight = scrollPanelScrollHeight - scrollPanelHeight - this.scrollPanel.el.scrollTop;
  if(lastHeight < this.accuracy) {
    lastHeight = 0;
  }
  var time = Math.abs(Math.ceil(lastHeight / deltaY));
  var top = scrollPanelHeight - (height + (time * this.vScrollBar.innerDeltaY));
  return top;
}
Nach dem Login kopieren

5. Achten Sie auf Scroll-Ereignisse.

// ...
  on: {
    wheel: vm.wheel
  }
  // ...
   wheel(e) {
    var vm = this;
    vm.showVBar();
    vm.scrollVBar(e.deltaY > 0 ? 1 : -1, 1);
    e.stopPropagation();
  }
  // ...
Nach dem Login kopieren

6. Achten Sie auf Ziehereignisse in der Bildlaufleiste

listenVBarDrag: function() {
    var vm = this;
    var y;
    var _y;
    function move(e) {
      _y = e.pageY;
      var _delta = _y - y;
      vm.scrollVBar(_delta > 0 ? 1 : -1, Math.abs(_delta / vm.vScrollBar.innerDeltaY));
      y = _y;
    }
    function t(e) {
      var deltaY = {
        deltaY: vm.vScrollBar.ops.deltaY
      };
      if(!vm.getVBarHeight(deltaY)) {
        return;
      }
      vm.mousedown = true;
      y = e.pageY; // 记录初始的Y的位置
      vm.showVBar();
      document.addEventListener(&#39;mousemove&#39;, move);
      document.addEventListener(&#39;mouseup&#39;, function(e) {
        vm.mousedown = false;
        vm.hideVBar();
        document.removeEventListener(&#39;mousemove&#39;, move);
      });
    }
    this.listeners.push({
      dom: vm.vScrollBar.el,
      event: t,
      type: "mousedown"
    });
    vm.vScrollBar.el.addEventListener(&#39;mousedown&#39;, t); // 把事件放到数组里面,等销毁之前移除掉注册的时间。
  }
Nach dem Login kopieren

7. Das Prinzip ähnelt dem von Drag-Ereignissen, außer dass es eine zusätzliche Beurteilung gibt, um zu bestimmen, ob die aktuelle Richtung x oder y ist.

listenPanelTouch: function() {
    var vm = this;
    var pannel = this.scrollPanel.el;
    var x, y;
    var _x, _y;
    function move(e) {
      if(e.touches.length) {
        var touch = e.touches[0];
        _x = touch.pageX;
        _y = touch.pageY;
        var _delta = void 0;
        var _deltaX = _x - x;
        var _deltaY = _y - y;
        if(Math.abs(_deltaX) > Math.abs(_deltaY)) {
          _delta = _deltaX;
          vm.scrollHBar(_delta > 0 ? -1 : 1, Math.abs(_delta / vm.hScrollBar.innerDeltaX));
        } else if(Math.abs(_deltaX) < Math.abs(_deltaY)){
          _delta = _deltaY;
          vm.scrollVBar(_delta > 0 ? -1 : 1, Math.abs(_delta / vm.vScrollBar.innerDeltaY));
        }
        x = _x;
        y = _y;
      }
    }
    function t(e) {
      var deltaY = {
        deltaY: vm.vScrollBar.ops.deltaY
      };
      var deltaX = {
        deltaX: vm.hScrollBar.ops.deltaX
      };
      if(!vm.getHBarWidth(deltaX) && !vm.getVBarHeight(deltaY)) {
        return;
      }
      if(e.touches.length) {
        e.stopPropagation();
        var touch = e.touches[0];
        vm.mousedown = true;
        x = touch.pageX;
        y = touch.pageY;
        vm.showBar();
        pannel.addEventListener(&#39;touchmove&#39;, move);
        pannel.addEventListener(&#39;touchend&#39;, function(e) {
          vm.mousedown = false;
          vm.hideBar();
          pannel.removeEventListener(&#39;touchmove&#39;, move);
        });
      }
    }
    pannel.addEventListener(&#39;touchstart&#39;, t);
    this.listeners.push({
      dom: pannel,
      event: t,
      type: "touchstart"
    });
  }
Nach dem Login kopieren

8. Scrollen von Inhalten

Das Prinzip des Scrollens von Inhalten ist nichts anderes als das Ändern von scrollTop/scrollLeft des scrollPanels, um den Inhalt so zu steuern, dass er sich nach oben, unten, links und rechts bewegt.

scrollVBar: function(pos, time) {
    // >0 scroll to down <0 scroll to up
     
    var top = this.vScrollBar.state.top; 
    var scrollPanelHeight = getComputed(this.scrollPanel.el, &#39;height&#39;).replace(&#39;px&#39;, "");
    var scrollPanelScrollHeight = this.scrollPanel.el.scrollHeight;
    var scrollPanelScrollTop = this.scrollPanel.el.scrollTop;
    var height = this.vScrollBar.state.height;
    var innerdeltaY = this.vScrollBar.innerDeltaY;
    var deltaY = this.vScrollBar.ops.deltaY;
    if (!((pos < 0 && top <= 0) || (scrollPanelHeight <= top + height && pos > 0) || (Math.abs(scrollPanelScrollHeight - scrollPanelHeight) < this.accuracy))) {
      var Top = top + pos * innerdeltaY * time;
      var ScrollTop = scrollPanelScrollTop + pos * deltaY * time;
      if (pos < 0) {
        // scroll ip
        this.vScrollBar.state.top = Math.max(0, Top);
        this.scrollPanel.el.scrollTop = Math.max(0, ScrollTop);
      } else if (pos > 0) {
        // scroll down
        this.vScrollBar.state.top = Math.min(scrollPanelHeight - height, Top);
        this.scrollPanel.el.scrollTop = Math.min(scrollPanelScrollHeight - scrollPanelHeight, ScrollTop);
      }
    }
    // 这些是传递给父组件的监听滚动的函数的。
    var content = {};
    var bar = {};
    var process = "";
    content.residual = (scrollPanelScrollHeight - scrollPanelScrollTop - scrollPanelHeight);
    content.scrolled = scrollPanelScrollTop;
    bar.scrolled = this.vScrollBar.state.top;
    bar.residual = (scrollPanelHeight - this.vScrollBar.state.top - this.vScrollBar.state.height);
    bar.height = this.vScrollBar.state.height;
    process = bar.scrolled/(scrollPanelHeight - bar.height);
    bar.name = "vBar";
    content.name = "content";
    this.$emit(&#39;vscroll&#39;, bar, content, process);
  },
Nach dem Login kopieren

9. Zerstöre registrierte Ereignisse.

Gerade haben wir die registrierten Ereignisse in das Listeners-Array eingefügt und können sie im beforedestroy-Hook zerstören.

// remove the registryed event.
  this.listeners.forEach(function(item) {
    item.dom.removeEventListener(item.event, item.type);
  });
Nach dem Login kopieren

Bedienungs-Screenshot

Der PC-seitige Betriebs-Screenshot ist wie unten dargestellt:

Nach der Registrierung des Hörereignisses sieht er wie abgebildet aus unten:

Führen Sie den Screenshot auf Ihrem Telefon aus:

Es ist ersichtlich, dass der Leistungseffekt mit der nativen Bildlaufleiste übereinstimmt.

Fazit & Reflexion

Das Obige ist im Grunde das Design der Bildlaufleiste, die ich entworfen habe. Zunächst einmal bin ich den Nuggets sehr dankbar, dass sie mir so etwas gegeben haben Sharing-Plattform, und dann möchte ich mich bei slimScroll bedanken. Der Autor hat mich auf eine solche Idee gebracht. Nachdem ich dieses Plug-in fertiggestellt habe, weiß ich mehr über scrollWidth, scrollHeigh, scrollTop und scrollLeft von DOM-Elementen.

Das Obige habe ich für alle zusammengestellt. Ich hoffe, dass es in Zukunft für alle hilfreich sein wird.

Verwandte Artikel:

3 Grundmodi von Vue-Routing-Parametern (ausführliches Tutorial)

Verwandte Tricks in JavaScript

Dynamisches Importieren von Dateien im Webpack implementieren

Das obige ist der detaillierte Inhalt vonVirtuelle Bildlaufleisten etwa 2.x in vue.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!