Sample code for virtual scroll bar based on Vue.js 2.x

Remember that the previously opened source CMS project was previously seen, found that the menu on the left of this project has exceeded the width of Windows, I am curious why I didn’t scroll Why? Then I looked carefully and found a little div, then I tried to drag it, I found it as like the original scroll bar! You can find Slimscroll by viewing its source code, then I went to its github warehouse to see the source code, give me the feeling that I can also make the same scroll bar! Implemented by VUE!

Good, now we start our design scroll bar step:

Design scroll bar DOM

The first thing to think is: If you want to roll the content you need to scroll, the first thing is that its parent DOM must be fixed as a fixed length, that is, the excerpt is hidden, add a style: Overflow: hidden, So, add a packaging to the content you want to scroll, make it equal to the parent DOM, then there is a style called: Overflow: hidden, this packaging element is called scrollpanel

Second: We know, We have to be as strong as the native scroll bar! It is necessary to design a horizontal scroll bar and a vertical scroll bar, the scroll bar and the scrollpanel belong to the relationship between the brothers nodes, because the existence of the scroll bar cannot make the original style typography error, and support top, left to control its location, so the scroll bar Position must be absolute, well, our horizontal scroll bar is: hbar, vertical scroll bar is: vbar

Finally: We designed ScrollPanel, VBar, HBar, we need a parent Div to put them together , Then add a style: relative

Design component structure

First, our plug-in is a total of 4 components, three of whom are subcomponents, 1 is the parent component, respectively: Vuescroll (Parent Components), ScrollPanel (Package requires a sub-component of scrolling content), VBAR (vertical scrolling Article), HBAR (horizontal scroll bar) Second, let us design the functions of each component. The components here are divided into control layer components and display components (familiar with the classmates of React should be understood), and the display layer components completely complete the displayed features: VBAR, HBar, ScrollPanel, and control layer components are a bit similar to the CPU, which can control sub-components. Each state, such as width, high, color, transparency, location, etc. The control layer component is: Vuescroll.


HBar / VBAR These two are horizontal scroll bars and vertical scroll bars, respectively. The functionality achieved is the same, so the old is put together, here is VBAR as an example.

PROPS receives the attribute passing through the parent component, specifically:

{height: vm.state.height + ‘PX’, / / Roller bar Width: vm.ops.width, // Rolling Bar Width Position: ‘Absolute’, Background: VM.Ops.Background, // Rolling Bar Background Color Top: + ‘PX’ , // Turns: ‘opacity .5s’, // Disappearance / Display Time Cursor: ‘Pointer’, // Opacity: Vm.State.opacity, / / ​​Transparency UserSelect: ‘None’}

2 The event is mainly when the mouse moves, the scroll bar is displayed.
 ... Render (_C) {RETURN _C (// ... {mouseenter: Function (e) {VM. $ EMIT ('Showvbar'); / / Trigger the parent component event, display the scroll bar}} // ...)}   Where State represents the state, it can change when running, and the OPS It is the configuration parameters and is the user passed. 

The components of the package scroll content are set to: Overflow: Hidden.
   VAR Style = Vm.ScrollContentStyle; style.overflow = 'hidden'; // ... {style: Style} // ... 
2, event

// … render _c) {// … on: {mouseEnter: function () {vm. $ EMIT (‘Showbar’);}, mouseeleave: function () {vm. $ EMIT (‘hidebar’);}}// …} // …


Control assembly. Control the status of the sub-component display, add various listening events, and the like.

1, acquire the DOM element of the child, used to obtain real-time information of the DOM.
 // ... 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 '] $ REFS ['HScrollBar']. $ EL;} // ...   2, display roller 
The scroll bar, including the display horizontal scroll bar and the display vertical scroll bar, here to display the vertical scroll bar as an example:

// … var temp; var deltay = { Deltay: this.vscrollbar.ops.deltay // Get user-configured deltay}; if (! this.ismouseeleavepanel || this.vscrollbar.ops.keepshow) {ix ((this.vscrollbar.state.Height =Temp = this.getvbarheight (DELTAY))) {// Judgment Condition / / Reset the status of the scroll bar = this.resizevbartop (THS.VSCROLLBAR.State.Height = Temp.height; “}} // …

}} // …
3, the height of the scroll bar is acquired

Because the height of the DOM element is not fixed, you have to get the true height of the DOM in real time, the highly calculated formula of the scroll bar is as follows:

VAR Height = Math.max (scrollpanelheight / screwpanelheight), this.vscrollbar.minbarHeight;

ie the height of the scroll bar: ScrollPanel’s height == ScrollPanel: DOM element height
 4, Resizevbartop, in order to prevent errors, and can find the height of the rolling bar from the parent element.   
Resizevbartop ({Height, ScrollPanelheight, ScrollpanelscrollHeight, Deltay}) {// CaCl the last height first var LastHeight = scrollpanelscrollHeight – ScrollPanelHeight – this.scrollpanel.el.scrolltop; if (LastHeight

5, the event of the roller scrolling.

// … ON: {Wheel: vm.wheel} // … Wheel (e) {var VM = this; vm.showvbar (); vm.scrollvbar (E.DELTAY> 0? 1: -1, 1); E.StopPropagation ();} // …
6, listening to roll Drag and drop incident

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; // Record the initial Y position VM.Showvbar (); Document.addeventListener (‘mousemove ” , Move); Document.addeventListener (‘Mouseup’, Function (E) {vm.mousedown = false; vm.hidevbar (); Document.RemoveEventListener (‘Mousemove’, Move);};} this.listener.push ( {DOM: VM.VScrollbar.el, Event: T, Type: “mousedown”}); vm.vscrollbar.l.addeventListener (‘mousedown’, t); // put the event in an array, remove before destruction Time to register. }

7, adapting the mobile terminal, listening to the Touch event. The principle is similar to the drag and drop, nothing more than a judgment, to determine that the current direction is x or y.
  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)  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 (! VM.GETHBARWIDTH (DELTAX) &&! VM.Getvbarheight (Deltay)) {Return;}}}}} {E.stoppropagation (); var touch = e.touches [0]; vm.mousedown = true; x = touch.pagex; y = touch.pagey; vm.showbar ); pannel.addEventListener ( 'touchmove', move); pannel.addEventListener ( 'touchend', function (e) {vm.mousedown = false; vm.hideBar (); pannel.removeEventListener ( 'touchmove', move);} );}} Pannel.addeventListener ('Touchstart', T); this.listeners.push ({Dom: Pannel, Event: T, Type: "TouchStart"});} 

8, rolling content

The principle of scrolling content is nothing more than changing the ScrollPanel’s scrolltop / scrollLeft to achieve the purpose of the control content.

Scrollvbar: Function (POS, TIME) {//> 0 SCRoll to Down
 0) || (Math.Abs ​​(ScrollPanelscrollHeight - ScrollPanelHeight)  0) {// scroll down = Math.min (ScrollPanelHeight - Height, TOP); this. ScrollPanel.el.scrollTop = Math.min (ScrollPanelscrollHeight - ScrollPanelHeight, ScrollTop);}} // These are functions that are passed to the monitor scrolling of the parent component. var content = {}; var bar = {}; var process = ""; content.residual = (scrollPanelScrollHeight - scrollPanelScrollTop - scrollPanelHeight); content.scrolled = scrollPanelScrollTop; bar.scrolled =; bar. residual = (scrollPanelHeight - - this.vScrollBar.state.height); bar.height = this.vScrollBar.state.height; process = bar.scrolled / (scrollPanelHeight - bar.height); = "vbar"; = "content"; this. $ EMIT ('vscroll', bar, content, process);}, < this.accuracy) {
    lastHeight = 0;
  var time = Math.abs(Math.ceil(lastHeight / deltaY));
  var top = scrollPanelHeight - (height + (time * this.vScrollBar.innerDeltaY));
  return top;

9, Destroy the registered event.

Just now put the registration event in the listners array, we can destroy them in the BeforeDestroy hook.
 // Remove the registryed Event. This.listener.Fore (item (item) {item.dom.removeEventListener (item.event, item.type);})   
Operation screenshot

PC end run screenshot as shown below:

 Register listening After the incident, as shown in the following figure:   Run screenshot on the mobile phone: 

It can be seen that rolling The performance effect is consistent.

    The above is basically the design of the scroll strip of my design, first grateful to the Nuggets to give me such a share. Platform, and then thanked the author of Slimscroll gave me such a thinking. After doing this plugin, I know more about the ScrollWidth, ScrollHeigh, Scrolltop, ScrollHeigh, Scrolltop, and Scrollleft, and attached to the GitHub project address 
The above part is the core source code of this component. I hope to help everyone’s learning, and alsoI hope everyone supports TUMI clouds.

© Copyright Notice
Just support it if you like
comment Grab the couch

Please log in to comment