简体   繁体   English

平滑的水平滚轮仅滚动

[英]Smooth horizontal wheel only scrolling

It is very annoing to hold shift when wheeling for horizontal scrolling.在水平滚动时按住 shift 是非常烦人的。 There are some ways to horizontally scrool with wheel only but they directly copy wheel deltaY into scrollLeft which results in uncomfortable jump-scrolling.有一些方法可以仅使用轮子进行水平滚动,但它们直接将轮子deltaY复制到scrollLeft中,这会导致不舒服的跳跃滚动。

Is there a mobile-friendly way to perform smooth horizontal scrolling on elements using wheel only?是否有一种适合移动设备的方式来仅使用滚轮对元素执行平滑的水平滚动? By "smooth" I mean something like default browser vertical wheel scroll behaviour. “流畅”是指默认浏览器垂直滚轮滚动行为。

Smooth scrolling can be achieved by using requestAnimationFrame .使用requestAnimationFrame可以实现平滑滚动。

You might want to play with denominator in getScrollStep function to adjust the smoothness of scrolling.您可能想在getScrollStep function 中使用分母来调整滚动的平滑度。

function horizontalWheel(container) {
  /** Max `scrollLeft` value */
  let scrollWidth;

  /** Desired scroll distance per animation frame */
  let getScrollStep = () => scrollWidth / 50 /* ADJUST TO YOUR WISH */ ;

  /** Target value for `scrollLeft` */
  let targetLeft;

  function scrollLeft() {
    let beforeLeft = container.scrollLeft;
    let wantDx = getScrollStep();
    let diff = targetLeft - container.scrollLeft;
    let dX = wantDx >= Math.abs(diff) ? diff : Math.sign(diff) * wantDx;

    // Performing horizontal scroll
    container.scrollBy(dX, 0);

    // Break if smaller `diff` instead of `wantDx` was used
    if (dX === diff)
      return;

    // Break if can't scroll anymore or target reached
    if (beforeLeft === container.scrollLeft || container.scrollLeft === targetLeft)
      return;

    requestAnimationFrame(scrollLeft);
  }

  container.addEventListener('wheel', e => {
    e.preventDefault();

    scrollWidth = container.scrollWidth - container.clientWidth;
    targetLeft = Math.min(scrollWidth, Math.max(0, container.scrollLeft + e.deltaY));

    requestAnimationFrame(scrollLeft);
  });
}

Just pass elements you want to horizontally scroll with wheel in this function:只需在此 function 中传递您想用滚轮水平滚动的元素:

let list = document.querySelector('.hList');
horizontalWheel(list);

Example:例子:

 function horizontalWheel(container) { /** Max `scrollLeft` value */ let scrollWidth; /** Desired scroll distance per animation frame */ let getScrollStep = () => scrollWidth / 50 /* ADJUST TO YOUR WISH */; /** Target value for `scrollLeft` */ let targetLeft; function scrollLeft() { let beforeLeft = container.scrollLeft; let wantDx = getScrollStep(); let diff = targetLeft - container.scrollLeft; let dX = wantDx >= Math.abs(diff)? diff: Math.sign(diff) * wantDx; // Performing horizontal scroll container.scrollBy(dX, 0); // Break if smaller `diff` instead of `wantDx` was used if (dX === diff) return; // Break if can't scroll anymore or target reached if (beforeLeft === container.scrollLeft || container.scrollLeft === targetLeft) return; requestAnimationFrame(scrollLeft); } container.addEventListener('wheel', e => { e.preventDefault(); scrollWidth = container.scrollWidth - container.clientWidth; targetLeft = Math.min(scrollWidth, Math.max(0, container.scrollLeft + e.deltaY)); requestAnimationFrame(scrollLeft); }); } // // Usage // window.addEventListener('load', () => { let list = document.querySelector('.hList'); horizontalWheel(list); });
 .hList { width: 300px; border: 2px solid red; display: flex; overflow: auto; }.element { display: flex; align-items: center; justify-content: center; color: white; font-family: sans-serif; flex-shrink: 0; width: 150px; height: 75px; background: green; border-right: 2px solid yellow; }.element:last-of-type { border: none; }
 <div class="hList"> <div class="element">Element 1</div> <div class="element">Element 2</div> <div class="element">Element 3</div> <div class="element">Element 4</div> <div class="element">Element 5</div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM