Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!doctype html>
<p>Scrollwheel normalizer. See <a href="http://stackoverflow.com/questions/5527601/normalizing-mousewheel-speed-across-browsers">this stackoverflow question</a> for the motivating problem.</p>
<div style="height: 400px; overflow: auto; background: #eee" id=thing>
<div style="border: 100px solid #eee; border-left-color: blue; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: yellow; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: green; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: red; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: blue; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: yellow; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: green; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: red; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: blue; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: yellow; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: green; width: 0; height: 0">&nbsp;</div>
<div style="border: 100px solid #eee; border-left-color: red; width: 0; height: 0">&nbsp;</div>
</div>
 
var normalizeWheelDelta = function() {
  // Keep a distribution of observed values, and scale by the
  // 33rd percentile.
  var distribution = [], done = null, scale = 30;
  return function(n) {
    // Zeroes don't count.
    if (n == 0) return n;
    // After 500 samples, we stop sampling and keep current factor.
    if (done != null) return n * done;
    var abs = Math.abs(n);
    // Insert value (sorted in ascending order).
    outer: do { // Just used for break goto
      for (var i = 0; i < distribution.length; ++i) {
        if (abs <= distribution[i]) {
          distribution.splice(i, 0, abs);
          break outer;
        }
      }
      distribution.push(abs);
    } while (false);
    // Factor is scale divided by 33rd percentile.
    var factor = scale / distribution[Math.floor(distribution.length / 3)];
    if (distribution.length == 500) done = factor;
    return n * factor;
  };
}();
// Usual boilerplate scroll-wheel incompatibility plaster.
var div = document.getElementById("thing");
div.addEventListener("DOMMouseScroll", grabScroll, false);
div.addEventListener("mousewheel", grabScroll, false);
function grabScroll(e) {
  var dx = -(e.wheelDeltaX || 0), dy = -(e.wheelDeltaY || e.wheelDelta || 0);
  if (e.detail != null) {
    if (e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
    else if (e.axis == e.VERTICAL_AXIS) dy = e.detail;
  }
  if (dx) {
    var ndx = Math.round(normalizeWheelDelta(dx));
    if (!ndx) ndx = dx > 0 ? 1 : -1;
    div.scrollLeft += ndx;
  }
  if (dy) {
    var ndy = Math.round(normalizeWheelDelta(dy));
    if (!ndy) ndy = dy > 0 ? 1 : -1;
    div.scrollTop += ndy;
  }
  if (dx || dy) { e.preventDefault(); e.stopPropagation(); }
}
Output 300px

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers