2010-12-02 21 views
3

Je reçois beaucoup de rapports indiquant que la roulette de la souris se comporte différemment dans différents navigateurs lors de l'utilisation de cette classe de barre de défilement. Dans certains navigateurs (comme Firefox), il est extrêmement lent alors que dans d'autres (surtout les nouvelles versions de Safari sur Snow Leopard) c'est parfait.Classe de barre de défilement JavaScript et vitesse de la molette de la souris dans différents navigateurs

Des idées ce qui se passe ici et comment y remédier? J'utilise la bibliothèque Mootools. Une ligne à faire attention à ici est la ligne wheel: (Browser.firefox) ? 20 : 1. C'est ici que vous définissez la vitesse ou les pas pour la molette de la souris.

Ici, il est mis en place dans un jsFiddle: 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

poster un exemple www.jsfiddle.net comment vous l'utilisez, ce n'est pas exactement évident - ou un lien vers une autre démo. –

+0

Ajouté dans le message original. –

+0

hrm event.wheel revient toujours comme -1 sur défiler vers le bas pour moi - dans ie8, ff 3.6.13 et chrome 7 - seulement firefox semble ok en raison de «this.options.wheel» étant 20. une raison particulière pour laquelle vous wouldn wouldn N'utilisez pas un pas de 20 pour tous les navigateurs? De plus, vous pouvez suivre le glisser via 'this.dragging = true;' et vérifier cela dans la fonction mouseleave qui cache la barre de défilement si vous passez la souris - vous ne devriez pas la faire disparaître en la faisant glisser. changez 'end' pour redéfinir' this.dragging' sur false et vérifiez si la souris est masquée afin de pouvoir la masquer si vous quittez le conteneur. –

Répondre

1

L'événement molette de la souris est très douteux en javascript, principal problème étant habituellement Safari car ils permettent de régler le rapport sur chaque version de points, et même alors, les valeurs rapportées par l'événement ne sont pas les mêmes dans tous les principaux navigateurs. Il y a quelque temps (link) il y a eu une discussion à ce sujet sur le tracker de MooTools et en comparant différentes solutions j'ai conclu qu'il n'y a pas de façon standard de normaliser l'événement. Le dernier message sur ce problème montre une solution possible pour la normalisation (link), mais il brise l'accélération de la roue dans Safari (et probablement toute autre accélération offerte par une autre combinaison Navigateur/OS/Souris), donc c'est un compromis devez évaluer si cela correspond aux exigences de votre scénario d'utilisation.

Questions connexes