web前端有滚动条的容器,我怎么能让他hover的时候自动滚动(滚动条跟着动)?

阅读 1k
2 个回答
function addAutoScroll(el: HTMLElement, offset = 1, delay = 1) {
  let interval: number | undefined

  el.addEventListener('mouseenter', () => {
    if (interval) clearInterval(interval)

    interval = setInterval(() => {
      el.scrollTo({ top: el.scrollHeight + offset, behavior: 'smooth' })
    }, delay)
  })

  el.addEventListener('mouseleave', () => {
    clearInterval(interval)
  })
}
export enum Position {
  down,
  up,
  left,
  right,
}
export interface AutoScrollOptions {
  speed: number;
  position: Position;
  abortController?: AbortController;
  // pause?: boolean;
}
export function autoScroll(container: HTMLElement, options: AutoScrollOptions) {
  function scrollTo(dist: number) {
    switch (options.position) {
      case Position.down:
        container?.scroll({ top: dist });
        break;
      case Position.up:
        container?.scroll({ top: dist });
        break;
      case Position.left:
        container?.scroll({ left: dist });
        break;
      case Position.right:
        container?.scroll({ left: dist });
        break;
      default:
        container?.scroll({ top: dist });
    }
  }
  function getMaxScroll() {
    switch (options.position) {
      case Position.down:
      case Position.up:
        return container.scrollHeight - container.clientHeight;
      case Position.left:
      case Position.right:
        return container.scrollWidth - container.clientWidth;
      default:
        return container.scrollHeight - container.clientHeight;
    }
  }
  function getInitialCurrentDist() {
    switch (options.position) {
      case Position.down:
      case Position.left:
        return 0;
      case Position.up:
      case Position.right:
        return getMaxScroll();
      default:
        return 0;
    }
  }
  const maxScroll = getMaxScroll();
  const isAdd =
    options.position === Position.down || options.position === Position.left;
  function getIsEnd(currentDist: number) {
    return isAdd ? currentDist >= maxScroll : currentDist <= 0;
  }
  let currentDist = getInitialCurrentDist();
  function loop() {
    if (options.abortController?.signal?.aborted) {
      return;
    }

    const isEnd = getIsEnd(currentDist);
    // 修复:直接执行滚动逻辑
    if (isEnd) {
      currentDist = isAdd ? 0 : maxScroll;
    } else {
      if (isAdd) {
        currentDist += options.speed;
      } else {
        currentDist -= options.speed;
      }
    }
    console.log(`currentDist`, currentDist);
    scrollTo(currentDist);
    requestAnimationFrame(loop);
  }
  loop();
}

搞了一个上下左右的版本

推荐问题