This article will share with you the method and code for simulating the scroll bar using native javascript, which is very effective. If you need it, you can refer to it. When there are many scroll bars on the page, they are nested with each other and are not nice-looking, then the scroll bar will be simulated, and the style of the scroll bar will be nice to make the page look beautiful.
When simulating a scroll bar, you often use the jquery plug-in and write a few lines of code. However, with the rapid development of mvvm, jquery is often too difficult to use. This is the motivation of this article. This document strives to use code that does not rely solely on jquery and only relies on mvvm (aveon) APIs, complete a simple scroll bar.
Requirements:
1. scroll wheel to make the scroll bar work and scroll the interface
2. You can drag the scroll bar and scroll the page.
3. When the page is resize, the scroll bar can still work according to the page size change.
Effect:
Obviously, this component is based on the drag. If you don't want to write it again, you only need to change the drag of the ui framework. Here, the drag component of the easy js ui is changed. Easy js is used because there are many annotations and the code is concise.
In this case, replace the corresponding method in the drag component of easy js ui with the method in aveon api, and delete the method and redundant code in prototype.
define('drag',['avalon-min'],function(avalon){ function getBoundary(container, target) { var borderTopWidth = 0, borderRightWidth = 0, borderBottomWidth = 0, borderLeftWidth = 0, cOffset = avalon(container) .offset(), cOffsetTop = cOffset.top, cOffsetLeft = cOffset.left, tOffset = avalon(target) .offset(); borderTopWidth = parseFloat(avalon.css(container,'borderTopWidth')); borderRightWidth = parseFloat(avalon.css(container,'borderRightWidth')); borderBottomWidth = parseFloat(avalon.css(container,'borderBottomWidth')); borderLeftWidth = parseFloat(avalon.css(container,'borderLeftWidth')); cOffsetTop = cOffsetTop - tOffset.top + parseFloat(avalon(target).css('top')); cOffsetLeft = cOffsetLeft - tOffset.left + parseFloat(avalon(target).css('left')); return { top : cOffsetTop + borderTopWidth, right : cOffsetLeft + avalon(container).outerWidth() - avalon(target).outerWidth() - borderRightWidth, left : cOffsetLeft + borderLeftWidth, bottom : cOffsetTop + avalon(container).outerHeight() - avalon(target).outerHeight() - borderBottomWidth }; } var drag = function(target, options) { var defaults = { axis:null, container:null, handle:null, ondragmove:null }; var o =avalon.mix(defaults,options), doc = target.ownerDocument, win = doc.defaultView || doc.parentWindow, originHandle=target, isIE =!-[1,], handle = isIE ? target :doc, container = o.container ?o.container: null, count = 0, drag = this, axis = o.axis, isMove = false, boundary, zIndex, originalX, originalY, clearSelect = 'getSelection' in win ? function(){ win.getSelection().removeAllRanges(); } : function(){ try{ doc.selection.empty(); } catch( e ){}; }, down = function( e ){ o.isDown = true; var newTarget = target, left, top, offset; o.width = avalon(target).outerWidth(); o.height = avalon(target).outerHeight(); o.handle = handle; left = avalon(newTarget).css( 'left' ); top = avalon(newTarget).css( 'top' ); offset = avalon(newTarget).offset(); drag.left = left = parseInt( left ); drag.top = top = parseInt( top ); drag.offsetLeft = offset.left; drag.offsetTop = offset.top; originalX = e.pageX - left; originalY = e.pageY - top; if( (!boundary && container)){ boundary = getBoundary(container, newTarget ); } if( axis ){ if( axis === 'x' ){ originalY = false; } else if( axis === 'y' ){ originalX = false; } } if( isIE ){ handle.setCapture(); } avalon.bind(handle,'mousemove',move); avalon.bind(handle,'mouseup',up); if( isIE ){ avalon.bind(handle,'losecapture',up); } e.stopPropagation(); e.preventDefault(); }, move = function( e ){ if( !o.isDown ){ return; } count++; if( count % 2 === 0 ){ return; } var currentX = e.pageX, currentY = e.pageY, style = target.style, x, y, left, right, top, bottom; clearSelect(); isMove = true; if( originalX ){ x = currentX - originalX; if( boundary ){ left = boundary.left; right = boundary.right; x = x < left ? left : x > right ? right : x; } drag.left = x; drag.offsetLeft = currentX - e.offsetX; style.left = x + 'px'; } if( originalY ){ y = currentY - originalY; if( boundary ){ top = boundary.top; bottom = boundary.bottom; y = y < top ? top : y > bottom ? bottom : y; } drag.top = y; drag.offsetTop = currentY - e.offsetY; style.top = y + 'px'; } o.ondragmove.call(this,drag); e.stopPropagation(); }, up = function( e ){ o.isDown = false; if( isIE ){ avalon.unbind(handle,'losecapture' ); } avalon.unbind( handle,'mousemove'); avalon.unbind( handle,'mouseup'); if( isIE ){ handle.releaseCapture(); } e.stopPropagation(); }; avalon(originHandle).css( 'cursor', 'pointer' ); avalon.bind( originHandle,'mousedown', down ); drag.refresh=function(){ boundary=getBoundary(container,target); }; }; return drag;});
In addition, a refresh () method is added to the last exposed drag to update the range that can be dragged by the scroll bar during resize. This method is used in the update view of scrollbar.
drag.refresh=function(){ boundary=getBoundary(container,target); };
You can also add a hook to move the scroll bar to allow a listener function to be added from the outside. When you drag the slider, the listener function is triggered and the drag parameter is input.
o.ondragmove.call(this,drag);
Then scrollbar. js
Define ('scrollbar', ['aveon-min', 'drag'], function (aveon, drag) {function scrollbar (wrap, scrollbar, height_per_scroll) {// container, scroll bar, the distance between every scroll wheel movement this. scroll_height = 0; // The height of the scroll bar this. dragger = null; // drag component instance wrap. scrollTop = 0; // The container position minus the default vertical position of the browser's outermost scroll bar var self = this, wrap_top = aveon (wrap ). offset (). top-aveon (document ). scrollTop (); function ondragmove (drag) {// listening function when the drag component is dragged to update the container view wrap. scrollTop = (parseFloat (scrollbar. style. top)-wrap_top) * (wrap. scrollHeight-wrap. clientHeight)/(wrap. clientHeight-self.scroll_height) ;}; function setScrollPosition (o) {// update the scroll bar position scrollbar. style. top = o. scrollTop * wrap. clientHeight/wrap. scrollHeight + wrap_top + 'px ';} function inti_events () {aveon. bind (wrap, 'mousewheel ', function (e) {if (e. wheelDelta <0) wrap. scrollTop + = height_per_scroll; else wrap. scrollTop-= height_per_scroll; setScrollPosition (wrap); e. preventDefault () ;}); self. dragger = new drag (scrollbar, {container: wrap, axis: 'y', ondragmove: ondragmove}); window. onresize = function () {self. refresh_views (); self. dragger. refresh () ;};} this. refresh_views = function () {// update all part views of the component and expose them for external calls. // specify the height of the container as the visible part of the browser-vertical position of the container, the containers include border, padding, and margin. you can modify wrap.style.height?document.doc umentElement according to the corresponding scenario. clientHeight-wrap_top + 'px '; self. scroll_height = wrap. clientHeight * wrap. clientHeight/wrap. scrollHeight; // The container height equals to the scroll bar height. Hide the scroll bar if (self. scroll_height = wrap. clientHeight) scrollbar. style. display = 'none'; else scrollbar. style. display = 'block'; scrollbar. style. height = self. scroll_height + 'px '; setScrollPosition (wrap);} function init () {self. refresh_views (); inti_events () ;}init () ;}return scrollbar ;});
We can see that the refresh method of the drag component is called during resize to update the range that can be dragged by the scroll bar. The refresh_views () method is exposed to cope with external views that need to be updated manually. For example, fold and expand a chat group.
This completes the simple scroll bar. The code is very simple. It is also easy to fix bugs or customize problems.
The above is all the content of this article. I hope you will like it.