159 votes

Normalisant mousewheel vitesse dans les navigateurs

Pour une autre question , j'ai composé cette réponse, y compris cet exemple de code.

Dans ce code j'utilise la molette de la souris pour effectuer un zoom in/out d'un HTML5 Canvas. J'ai trouvé un code qui normalise les différences de vitesse entre Chrome et Firefox. Cependant, le zoom de la manipulation dans Safari est beaucoup, beaucoup plus vite que dans l'un de ces.

Voici le code que j'ai actuellement:

var handleScroll = function(e){
  var delta = e.wheelDelta ? e.wheelDelta/40 : e.detail ? -e.detail/3 : 0;
  if (delta) ...
  return e.preventDefault() && false;
};
canvas.addEventListener('DOMMouseScroll',handleScroll,false); // For Firefox
canvas.addEventListener('mousewheel',handleScroll,false);     // Everyone else

Quel code dois-je utiliser pour obtenir le même "delta" de la valeur pour le même montant de la molette de la souris à rouler dans de Chrome v10/11, Firefox v4, Safari v5, Opéra v11 et IE9?

Cette question est liée, mais n'a pas de bonne réponse.

Edit: complément d'enquête montre qu'un événement scroll " up " est:

 | evt.wheelDelta | evt.détail
------------------+----------------+------------
 Safari v5/Win7 | 120 | 0
 Safari v5/OS X | 120 | 0
 Safari v7/OS X | 12 | 0
 Chrome v11/Win7 | 120 | 0
 Chrome v37/Win7 | 120 | 0
 Chrome v11/OS X | 3 (!) | 0 (éventuellement mal)
 Chrome v37/OS X | 120 | 0
 IE9/Win7 | 120 | undefined
 Opéra v11/OS X | 40 | -1
 Opéra v24/OS X | 120 | 0
 Opéra v11/Win7 | 120 | -3
 Firefox v4/Win7 | indéfini | -3
 Firefox v4/OS X | indéfini | -1
Firefox v30/OS X | indéfini | -1

En outre, en utilisant le trackpad de MacBook OS X donne des résultats différents en même lorsque vous vous déplacez lentement:

  • Sur Safari et Chrome, l' wheelDelta est une valeur de 3 au lieu de 120 pour la molette de la souris.
  • Sur Firefox, l' detail est habituellement 2, parfois, 1, mais lorsque le défilement très lentement, PAS de GESTIONNAIRE d'ÉVÉNEMENTS, les FEUX À TOUS.

La question est donc:

Quel est le meilleur moyen de différencier ce comportement (idéalement sans n'importe quel utilisateur de l'agent ou de l'OS sniffing)?

59voto

Phrogz Points 112337

Edition Septembre 2014

Étant donné que:

  • Différentes versions d'un même navigateur sur OS X, ont abouti à des valeurs différentes dans le passé, et peut le faire dans l'avenir, et que
  • À l'aide du trackpad sur OS X, les rendements très similaire effets à l'aide de la molette de la souris, mais donne très différents événements valeurs, et pourtant l'appareil différence ne peut pas être détecté par JS

...Je ne peux que recommander l'utilisation de ce simple, connectez-vous en fonction de comptage de code:

var handleScroll = function(evt){
  if (!evt) evt = event;
  var direction = (evt.detail<0 || evt.wheelDelta>0) ? 1 : -1;
  // Use the value as you will
};
someEl.addEventListener('DOMMouseScroll',handleScroll,false); // for Firefox
someEl.addEventListener('mousewheel',    handleScroll,false); // for everyone else

Original tentative correcte de la façon suivante.

Voici ma première tentative de script pour normaliser les valeurs. Il a deux défauts sur OS X: Firefox OS X va produire des valeurs 1/3 de ce qu'ils devraient être, et Chrome OS X va produire des valeurs de 1 / 40ème de ce qu'elles devraient être.

// Returns +1 for a single wheel roll 'up', -1 for a single roll 'down'
var wheelDistance = function(evt){
  if (!evt) evt = event;
  var w=evt.wheelDelta, d=evt.detail;
  if (d){
    if (w) return w/d/40*d>0?1:-1; // Opera
    else return -d/3;              // Firefox;         TODO: do not /3 for OS X
  } else return w/120;             // IE/Safari/Chrome TODO: /3 for Chrome OS X
};

Vous pouvez tester ce code sur votre propre navigateur ici: http://phrogz.net/JS/wheeldelta.html

Suggestions pour la détection et l'amélioration du comportement sur Firefox et Chrome OS X sont les bienvenus.

Edit: Une suggestion de @Tom est tout simplement de compter chaque événement d'appeler un seul mouvement, en utilisant le signe de la distance pour l'ajuster. Ce ne sera pas donner d'excellents résultats sous lisse accélérée de défilement sur OS X, ni de gérer parfaitement le cas lorsque la molette de la souris est déplacé très rapidement (par exemple, wheelDelta 240), mais cela n'arrive que rarement. Ce code est maintenant la technique recommandée indiquée en haut de cette réponse, pour les raisons qui y sont décrits.

28voto

smrtl Points 422

Voici ma tentative folle pour produire un delta de Croix navigateur cohérente et normalisée (-1 ``

C’est totalement empirique mais fonctionne assez bien sur Safari 6, 16 FF, Opera 12 (OS X) et IE 7 sur XP

12voto

Sergio Points 16402

J'ai fait un tableau avec les différentes valeurs renvoyées par les différents événements/navigateurs, en tenant compte de la DOM3 wheel événement que certains navigateurs prennent déjà en charge (tableau).

Basé sur que j'ai fait cette fonction pour normaliser la vitesse:

http://jsfiddle.net/mfe8J/1/

function normalizeWheelSpeed(event) {
    var normalized;
    if (event.wheelDelta) {
        normalized = (event.wheelDelta % 120 - 0) == -0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
    } else {
        var rawAmmount = event.deltaY ? event.deltaY : event.detail;
        normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
    }
    return normalized;
}

Table pour mousewheel, wheel et DOMMouseScroll événements:

| mousewheel        | Chrome (win) | Chrome (mac) | Firefox (win) | Firefox (mac) | Safari 7 (mac) | Opera 22 (mac) | Opera 22 (win) | IE11      | IE 9 & 10   | IE 7 & 8  |
|-------------------|--------------|--------------|---------------|---------------|----------------|----------------|----------------|-----------|-------------|-----------|
| event.detail      | 0            | 0            | -             | -             | 0              | 0              | 0              | 0         | 0           | undefined |
| event.wheelDelta  | 120          | 120          | -             | -             | 12             | 120            | 120            | 120       | 120         | 120       |
| event.wheelDeltaY | 120          | 120          | -             | -             | 12             | 120            | 120            | undefined | undefined   | undefined |
| event.wheelDeltaX | 0            | 0            | -             | -             | 0              | 0              | 0              | undefined | undefined   | undefined |
| event.delta       | undefined    | undefined    | -             | -             | undefined      | undefined      | undefined      | undefined | undefined   | undefined |
| event.deltaY      | -100         | -4           | -             | -             | undefined      | -4             | -100           | undefined | undefined   | undefined |
| event.deltaX      | 0            | 0            | -             | -             | undefined      | 0              | 0              | undefined | undefined   | undefined |
|                   |              |              |               |               |                |                |                |           |             |           |
| wheel             | Chrome (win) | Chrome (mac) | Firefox (win) | Firefox (mac) | Safari 7 (mac) | Opera 22 (mac) | Opera 22 (win) | IE11      | IE 10 & 9   | IE 7 & 8  |
| event.detail      | 0            | 0            | 0             | 0             | -              | 0              | 0              | 0         | 0           | -         |
| event.wheelDelta  | 120          | 120          | undefined     | undefined     | -              | 120            | 120            | undefined | undefined   | -         |
| event.wheelDeltaY | 120          | 120          | undefined     | undefined     | -              | 120            | 120            | undefined | undefined   | -         |
| event.wheelDeltaX | 0            | 0            | undefined     | undefined     | -              | 0              | 0              | undefined | undefined   | -         |
| event.delta       | undefined    | undefined    | undefined     | undefined     | -              | undefined      | undefined      | undefined | undefined   | -         |
| event.deltaY      | -100         | -4           | -3            | -0,1          | -              | -4             | -100           | -99,56    | -68,4 | -53 | -         |
| event.deltaX      | 0            | 0            | 0             | 0             | -              | 0              | 0              | 0         | 0           | -         |
|                   |              |              |               |               |                |                |                |           |             |           |
|                   |              |              |               |               |                |                |                |           |             |           |
| DOMMouseScroll    |              |              | Firefox (win) | Firefox (mac) |                |                |                |           |             |           |
| event.detail      |              |              | -3            | -1            |                |                |                |           |             |           |
| event.wheelDelta  |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.wheelDeltaY |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.wheelDeltaX |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.delta       |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.deltaY      |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.deltaX      |              |              | undefined     | undefined     |                |                |                |           |             |           |

6voto

Marijn Points 2510

Un autre plus ou moins une solution autonome à http://jsbin.com/iqafek/2/edit .

Cela ne prend pas de temps entre les événements en compte cependant. Certains navigateurs semblent toujours déclencher des événements avec la même delta et juste les incendies plus rapidement lors du défilement rapidement. D’autres ne varient pas les deltas. On peut imaginer un normalisateur adaptative qui tient compte de temps, mais qui obtiendrait un peu impliqués et difficile à utiliser.

3voto

robocat Points 1567

Pour la prise en charge du zoom sur les appareils tactiles, vous inscrire à la gesturestart, gesturechange et gestureend événements et l'utilisation de l'événement.à l'échelle de la propriété. Vous pouvez voir un exemple de code pour cela.

Pour Firefox 17 onwheel événement est prévu pour être pris en charge par les versions de bureau et mobile (comme par MDN docs sur onwheel). Aussi pour Firefox peut-être le Gecko spécifique MozMousePixelScroll événement est utile (bien que sans doute c'est maintenant obsolète depuis la DOMMouseWheel événement est maintenant obsolète dans Firefox).

Pour Windows, le pilote lui-même semble générer WM_MOUSEWHEEL, WM_MOUSEHWHEEL événements (et peut-être le WM_GESTURE événement pour tablette tactile panoramique?). Qui pourrait expliquer pourquoi Windows ou le navigateur ne semble pas à normaliser la molette de la souris valeurs de l'événement lui-même (et peut-être que vous ne pouvez pas écrire de code fiable pour normaliser les valeurs).

Pour onwheel (pas onmousewheel) manifestation de soutien dans Internet Explorer pour IE9 et IE10, vous pouvez également utiliser le standard du W3C onwheel événement. Cependant, l'une encoche peut être une valeur différente de 120 (par exemple, un cran devient 111 (au lieu de -120) sur ma souris à l'aide de cette page de test). J'ai écrit un autre article avec d'autres détails de la roue des événements qui pourraient être pertinents.

En gros, dans mes propres tests pour les événements de la roulette (je suis en train de normaliser les valeurs de défilement), j'ai constaté que je reçois des différentes valeurs pour les OS, le navigateur, le fournisseur, la version du navigateur, le type d'événement, et de l'appareil (Microsoft tiltwheel de la souris, ordinateur portable, tablette tactile gestes, ordinateur portable, tablette tactile avec scrollzone, Apple magic mouse d'Apple mighty mouse scrollball, Mac, tablette tactile, etc etc).

Et ignorer une variété d'effets secondaires de la configuration de votre navigateur (par exemple Firefox molette de la souris.enable_pixel_scrolling, chrome, faites défiler jusqu'-pixels=150), les paramètres de pilote (par exemple, Synaptics touchpad), et les OS de configuration (Windows paramètres de la souris, OSX préférences de la Souris, X.org bouton paramètres).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X