2010-12-02 11 views
3

このスクロールバークラスを使用すると、マウスホイールがブラウザによって異なる動作をするという報告が多くあります。いくつかのブラウザ(Firefoxのようなもの)では非常に遅いが、他のもの(ほとんどがSnow LeopardのSafariの新しいバージョン)では完璧だ。JavaScriptのスクロールバークラスとマウスホイールの速度が異なるブラウザ

ここで何が起こっているのか、それを修正する方法はありますか?私はMootoolsライブラリを使用しています。ここで注意すべき1行はwheel: (Browser.firefox) ? 20 : 1行です。これは、マウスホイールの速度またはステップを設定する場所です。

ここではjsFiddleに設定されている:彼らはすべてのポイントリリースの比率を調整するために使用されるように、マウスホイールイベントはJavaScriptで非常に危険なであるhttp://jsfiddle.net/brandondurham/6SUyM/

var ScrollBar = new Class({ 

    Implements: [Events, Options], 

    options: { 
     wheel: (Browser.firefox) ? 20 : 1 
    }, 

    initialize: function(main, options) { 

     this.setOptions(options); 

     this.main = $(main); 
     this.content = this.main.getFirst(); 

     this.vScrollbar = new Element('div', { 
      'class': 'scrollbar' 
     }).inject(this.content, 'after'); 

     this.vTrack = new Element('div', { 
      'class': 'track' 
     }).inject(this.vScrollbar); 

     this.vThumb = new Element('div', { 
      'class': 'handle' 
     }).inject(this.vTrack); 

     this.bound = { 
      'vStart': this.vStart.bind(this), 
      'end': this.end.bind(this), 
      'vDrag': this.vDrag.bind(this), 
      'vTouchDrag': this.vTouchDrag.bind(this), 
      'wheel': this.wheel.bind(this), 
      'vPage': this.vPage.bind(this), 
     }; 

     this.vScrollbar.set('tween', { 
      duration: 200, 
      transition: 'cubic:out' 
     }); 
     this.main.addEvent('mouseenter', function(event){ 
      this.vScrollbar.get('tween').cancel(); 
      this.vScrollbar.tween('width', 12); 
     }.bind(this)); 
     this.main.addEvent('mouseleave', function(event){ 
      this.vScrollbar.get('tween').cancel(); 
      this.vScrollbar.tween('width', 0); 
     }.bind(this)); 

     this.vPosition = {}; 
     this.vMouse = {}; 
     this.update(); 
     this.attach(); 

     this.scrollContent = new Fx.Scroll(this.content, { 
      duration: 800, 
      transition: Fx.Transitions.Cubic.easeOut, 
     }); 
     this.scrollThumb = new Fx.Morph(this.vThumb, { 
      duration: 400, 
      transition: Fx.Transitions.Cubic.easeOut, 
     }); 
    }, 

    update: function() { 

     var panel_id = (this.content.getFirst()) ? this.content.getFirst().get('id') : ''; 

     if ((this.content.scrollHeight <= this.main.offsetHeight) || panel_id == 'random-doodle') this.main.addClass('noscroll'); 
     else this.main.removeClass('noscroll'); 

     this.vContentSize = this.content.offsetHeight; 
     this.vContentScrollSize = this.content.scrollHeight; 
     this.vTrackSize = this.vTrack.offsetHeight; 

     this.vContentRatio = this.vContentSize/this.vContentScrollSize; 

     this.vThumbSize = (this.vTrackSize * this.vContentRatio).limit(12, this.vTrackSize); 

     this.vScrollRatio = this.vContentScrollSize/this.vTrackSize; 

     this.vThumb.setStyle('height', this.vThumbSize); 

     this.vUpdateThumbFromContentScroll(); 
     this.vUpdateContentFromThumbPosition(); 

    }, 

    vUpdateContentFromThumbPosition: function() { 
     this.content.scrollTop = this.vPosition.now * this.vScrollRatio; 
    }, 

    vUpdateContentFromThumbPosition2: function() { 
     var pos = this.vPosition.now * this.vScrollRatio; 
     this.scrollContent.start(0, pos); 
    }, 

    vUpdateThumbFromContentScroll: function() { 
     this.vPosition.now = (this.content.scrollTop/this.vScrollRatio).limit(0, (this.vTrackSize - this.vThumbSize)); 
     this.vThumb.setStyle('top', this.vPosition.now); 
    }, 

    vUpdateThumbFromContentScroll2: function(pos) { 
     this.vPosition.now = (this.content.scrollTopNew/this.vScrollRatio).limit(0, (this.vTrackSize - this.vThumbSize));   
     this.scrollThumb.start({ 
      'top': this.vPosition.now  
     }); 
    }, 

    attach: function() { 
     if (this.options.wheel) this.content.addEvent('mousewheel', this.bound.wheel); 
     this.content.addEvent('touchstart', this.bound.vStart); 
     this.vThumb.addEvent('mousedown', this.bound.vStart); 
     this.vTrack.addEvent('mouseup', this.bound.vPage); 
    }, 

    wheel: function(event) { 
     this.content.scrollTop -= event.wheel * this.options.wheel; 
     this.vUpdateThumbFromContentScroll(); 
     event.stop(); 
    }, 

    scrollTo: function(pos){ 
     myInstance = this; 
     this.content.scrollTopNew = pos; 
     this.scrollContent.start(0, this.content.scrollTopNew); 
     myInstance.vUpdateThumbFromContentScroll2(pos); 
    }, 

    vPage: function(event) { 
     // if scrolling up 
     if (event.page.y > this.vThumb.getPosition().y) { 
      myInstance = this; 
      this.content.scrollTopNew = this.content.scrollTop.toInt() + this.content.offsetHeight.toInt(); 
      this.scrollContent.start(0, this.content.scrollTopNew); 
     } 
     // if scrolling down 
     else { 
      myInstance = this;  
      this.content.scrollTopNew = this.content.scrollTop.toInt() - this.content.offsetHeight.toInt();  
      this.scrollContent.start(0, this.content.scrollTopNew);  
     } 
     myInstance.vUpdateThumbFromContentScroll2(event.page.y); 
     event.stop(); 
    }, 

    vStart: function(event) { 
     this.vMouse.start = event.page.y; 
     this.vPosition.start = this.vThumb.getStyle('top').toInt(); 
     document.addEvent('touchmove', this.bound.vTouchDrag); 
     document.addEvent('touchend', this.bound.end); 
     document.addEvent('mousemove', this.bound.vDrag); 
     document.addEvent('mouseup', this.bound.end); 
     this.vThumb.addEvent('mouseup', this.bound.end); 
     event.stop(); 
    }, 

    end: function(event) { 
     document.removeEvent('touchmove', this.bound.vTouchDrag); 
     document.removeEvent('mousemove', this.bound.vDrag); 
     document.removeEvent('mouseup', this.bound.end); 
     this.vThumb.removeEvent('mouseup', this.bound.end); 
     event.stop(); 
    }, 

    vTouchDrag: function(event) { 
     this.vMouse.now = event.page.y; 
     this.vPosition.now = (this.vPosition.start - (this.vMouse.now - this.vMouse.start)).limit(0, (this.vTrackSize - this.vThumbSize)); 
     this.vUpdateContentFromThumbPosition(); 
     this.vUpdateThumbFromContentScroll(); 
     event.stop(); 
    }, 

    vDrag: function(event) { 
     this.vMouse.now = event.page.y; 
     this.vPosition.now = (this.vPosition.start + (this.vMouse.now - this.vMouse.start)).limit(0, (this.vTrackSize - this.vThumbSize)); 
     this.vUpdateContentFromThumbPosition(); 
     this.vUpdateThumbFromContentScroll(); 
     event.stop(); 
    } 

}); 
+0

ポストa www.jsfiddle.netの使い方、それが明白でない - または別のデモへのリンク。 –

+0

元の投稿に追加されました。 –

+0

hrm event.wheelは、私のためにスクロールダウンして-1に戻ってきます。ie8、ff 3.6.13、およびchrome 7 - firefoxは 'this.options.wheel'が20になっているように思われます。すべてのブラウザで20のステップを使用しないでください。また、 'this.dragging = true; 'を使ってドラッグを追跡して、マウスが動いた場合にスクロールバーを隠すmouseleave関数でそれを確認することもできます。ドラッグしている間は消えないようにしてください。 'end'を' this.dragging'を再びfalseに設定して、マウスが出ているかどうかをチェックして、コンテナを出ても隠れるようにします。 –

答えて

1

主な問題は、通常サファリされて、それでもイベントによって報告された値はすべての主要なブラウザで同じではありません。

MooToolsトラッカーでこれまでにいくつかの議論がありましたが(link)、さまざまなソリューションを比較すると、イベントを標準化する標準的な方法はないと結論づけました。
この問題の最後のメッセージは、(link)の正規化のための解決策を示していますが、Safariのホイールアクセラレーション(および他のブラウザ/ OS /マウスドライバの組み合わせが提供する他のアクセラレーション)を破ります。使用シナリオの要件に適合しているかどうかを評価する必要があります。

関連する問題