Rumah > Artikel > hujung hadapan web > Native js melaksanakan kemahiran scroll bar_javascript simulasi
Apabila terdapat banyak bar skrol pada halaman dan ia bersarang di antara satu sama lain, yang sangat tidak sedap dipandang, bar skrol akan disimulasikan dan bar skrol akan diberi gaya yang menarik untuk menjadikan halaman itu cantik.
Untuk mensimulasikan bar skrol, anda sering menggunakan pemalam jquery, dan kemudian tulis beberapa baris kod untuk menyelesaikannya. Walau bagaimanapun, dengan perkembangan pesat mvvm, banyak kali saya terlalu malas untuk menggunakan jquery Ini adalah motivasi artikel ini. untuk melengkapkan bar skrol mudah.
Keperluan:
1. Roda tetikus boleh membuat bar skrol berfungsi dan skrol antara muka
2. Tetikus boleh menyeret bar skrol dan membuat skrol antara muka
3. Apabila halaman diubah saiz, bar skrol berubah mengikut saiz halaman dan masih boleh berfungsi
Kesan:
Jelas sekali, komponen ini berdasarkan seretan saya tidak mahu menulisnya semula, jadi saya perlu menukar seretan rangka kerja ui Apa yang saya ubah di sini ialah komponen seretan mudah js. Easy js digunakan kerana terdapat lebih banyak komen dan kodnya ringkas.
Artikel ini menggantikan kaedah yang sepadan dalam komponen seret easy js ui dengan kaedah dalam avalon api dan memadamkan kaedah dan kod berlebihan dalam prototaip
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; });
Selain itu, kaedah refresh() ditambahkan pada seret terdedah terakhir, yang digunakan untuk mengemas kini julat boleh seret bar skrol semasa mengubah saiz. Kaedah ini akan digunakan dalam paparan kemas kini bar skrol.
drag.refresh=function(){ boundary=getBoundary(container,target); };
Selain itu, semasa proses menyeret bar skrol, tambahkan cangkuk untuk membolehkan fungsi mendengar ditambahkan dari luar Fungsi mendengar akan dicetuskan apabila menyeret, dan parameter seretan akan dihantar masuk.
o.ondragmove.call(this,drag);
Kemudian scrollbar.js
define('scrollbar',['avalon-min','drag'],function(avalon,drag){ function scrollbar(wrap,scrollbar,height_per_scroll){//容器,滚动条,每次滚轮移动的距离 this.scroll_height=0;//滚动条高度 this.dragger=null;//drag组件实例 wrap.scrollTop=0; //容器的位置要减去浏览器最外面的默认滚动条垂直方向位置 var self=this,wrap_top=avalon(wrap).offset().top-avalon(document).scrollTop(); function ondragmove(drag){//drag组件拖动时的监听函数,更新容器视图 wrap.scrollTop=(parseFloat(scrollbar.style.top)-wrap_top)* (wrap.scrollHeight -wrap.clientHeight)/(wrap.clientHeight-self.scroll_height); }; function setScrollPosition(o) {//更新滚动条位置 scrollbar.style.top =o.scrollTop*wrap.clientHeight/wrap.scrollHeight+wrap_top+ 'px'; } function inti_events(){ avalon.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(){//更新组件所有部分视图,并暴露供外部调用 //容器高度这里设置成浏览器可视部分-容器垂直方向位置,没有考虑容器有border,padding,margin.可根据相应场景修改 wrap.style.height=document.documentElement.clientHeight-wrap_top+'px'; self.scroll_height=wrap.clientHeight*wrap.clientHeight/wrap.scrollHeight; //容器高度等于滚动条高度,隐藏滚动条 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; });
Anda boleh melihat bahawa semasa mengubah saiz, kaedah muat semula komponen seret dipanggil untuk mengemas kini julat boleh seret bar skrol. Kaedah refresh_views() didedahkan di sini untuk menangani situasi luaran di mana paparan perlu dikemas kini secara manual. Contohnya, keruntuhan dan pengembangan kumpulan sembang.
Ini melengkapkan bar skrol ringkas. Kod ini sangat mudah, dan jika berlaku masalah dan anda perlu membetulkan pepijat atau menyesuaikannya, ia adalah mudah.
Di atas adalah keseluruhan kandungan artikel ini, saya harap anda semua menyukainya.