2010-12-02 4 views
3

У меня появилось много сообщений о том, что колесико мыши ведет себя по-разному в разных браузерах при использовании этого класса прокрутки. В некоторых браузерах (например, в Firefox) это очень медленно, в то время как в других (в основном, более новые версии Safari на Snow Leopard) это идеально.Класс прокрутки Javascript и скорость колесика мыши в разных браузерах

Любые идеи, что здесь происходит и как это исправить? Я использую библиотеку Mootools. Одна линия, на которую нужно обратить внимание, - это линия wheel: (Browser.firefox) ? 20 : 1. Здесь вы устанавливаете скорость или шаги для колесика мыши.

Здесь устанавливается в 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

отправьте пример www.jsfiddle.net, как вы его используете, его не совсем очевидно - или ссылка на другую демонстрацию. – 2010-12-02 23:18:10

ответ

1

Мышь событие колеса очень изворотливое в JavaScript, главным вопросом является, как правило, Safari, как они используются для настройки коэффициента на каждый выпуск, и даже тогда значения, сообщенные событием, не совпадают во всех основных браузерах.

Было некоторое обсуждение об этом на трекере MooTools некоторое время назад (link) и сравнение различных решений. Я пришел к выводу, что стандартного способа нормализации события нет.
Последнее сообщение по этому вопросу показывает возможное решение для нормализации (link), но оно прерывает ускорение колес в Safari (и, возможно, любое другое ускорение, которое предлагает другая комбинация браузера/OS/Mouse Driver), поэтому это компромисс, который вы будете должны оценить, соответствует ли это требованиям вашего сценария использования.