首页 > 解决方案 > 在按键上应用滚动动画与在鼠标单击时相同

问题描述

我有一个水平展开的页面,可以通过鼠标单击或按Space BarPage Up / Page DownLeft Arrow / Right ArrowHome / End键滚动。

通过鼠标点击激活的滚动使用Animate Plus.

使用按键滚动时如何获得完全相同的动画?

由于我的代码不会在 Stack Overflow 的代码段中运行,因此我将其发布到 Codepen。

这是我的完整代码:

https://codepen.io/boletrone/pen/MWWZrPQ

下面是我的 JavaScript 代码:

import animate from "https://cdn.jsdelivr.net/npm/animateplus@2/animateplus.js"

// Scroll on key presses
// =====================

let scrollPosition = 0
const maxScrollPosition = document.body.scrollWidth - window.innerWidth
const container = document.scrollingElement

window.onload = () => {
  document.body.onkeydown = event => {
    switch (event.code) {
      case "Space":
      case "PageDown":
      case "ArrowRight":
      case "ArrowDown": {
        event.preventDefault()

        if (scrollPosition === maxScrollPosition) return // If at the end, return
        scrollPosition += window.innerWidth
        break
      }
      case "PageUp":
      case "ArrowLeft":
      case "ArrowUp": {
        event.preventDefault()

        if (scrollPosition === 0) return // If at the beginning, return
        scrollPosition -= window.innerWidth
        break
      }
      case "Home": {
        scrollPosition = 0
        break
      }
      case "End": {
        scrollPosition = container.scrollWidth
        break
      }
    }

    container.scrollTo({
      top: 0,
      left: scrollPosition
    })
  }
}

// Scroll on mouse clicks
// ======================

const goToPreviousSectionButton = document.createElement("button")
const goToNextSectionButton = document.createElement("button")

document.body.appendChild(goToPreviousSectionButton)
document.body.appendChild(goToNextSectionButton)

const sections = Array.from(document.querySelectorAll("section")).sort(
  (s1, s2) => {
    return s1.getBoundingClientRect().left - s2.getBoundingClientRect().left
  }
)

const getSectionInView = () => {
  const halfWidth = window.innerWidth / 2
  const index = sections.findIndex(
    section =>
      section.getBoundingClientRect().left <= halfWidth &&
      section.getBoundingClientRect().right > halfWidth
  )
  return index
}

const getNextSection = dir => {
  const sectionInViewIndex = getSectionInView()
  const nextIndex = sectionInViewIndex + dir
  const numSections = sections.length
  const nextSectionIndex =
    nextIndex < 0 || nextIndex >= numSections ? sectionInViewIndex : nextIndex
  return sections[nextSectionIndex]
}

const animateScroll = dir => {
  const from = container.scrollLeft
  const { left } = getNextSection(dir).getBoundingClientRect()
  return progress => (container.scrollLeft = from + progress * left)
}

goToPreviousSectionButton.addEventListener("click", () => {
  animate({
    easing: "out-quintic",
    change: animateScroll(-1)
  })
})

goToNextSectionButton.addEventListener("click", () => {
  animate({
    easing: "out-quintic",
    change: animateScroll(1)
  })
})

标签: javascriptcssecmascript-6keyboard-eventsanimateplus

解决方案


您可以在“开关”中使用ArrowRightArrowLeft案例。下面的用法将解决问题。

import animate from "https://cdn.jsdelivr.net/npm/animateplus@2/animateplus.js"

// Scroll on key presses
// =====================

let scrollPosition = 0
const maxScrollPosition = document.body.scrollWidth - window.innerWidth
const container = document.scrollingElement

window.onload = () => {
  document.body.onkeydown = event => {
    switch (event.code) {
      case "Space":
      case "PageDown":
      case "ArrowRight":
        {
          scrollPosition++;
           if (scrollPosition === 3) return 
            event.preventDefault()
            animate({
              easing: "out-quintic",
              change: animateScroll(1)
            })
            break
        }
      case "ArrowLeft":
        {
            scrollPosition--;
           if (scrollPosition === 0) return 
            event.preventDefault()
            animate({
              easing: "out-quintic",
              change: animateScroll(-1)
            })
            break
        }
      case "PageUp": 
      case "Home": { 
        if(scrollPosition === 1)
         {
             animate({
              easing: "out-quintic",
              change: animateScroll(-1)
            }) 
         }else
         {
           animate({
             easing: "out-quintic",
             change: animateScroll(-2)
           })
         } 
        scrollPosition = 0;
        break
      }
      case "End": { 
         if(scrollPosition === 1)
         {
             animate({
              easing: "out-quintic",
              change: animateScroll(1)
            })  
         }else
           {
               animate({
                easing: "out-quintic",
                change: animateScroll(2)
              })
           }

        scrollPosition = 2;
        break
      }
    }


  }
}

// Scroll on mouse clicks
// ======================

const goToPreviousSectionButton = document.createElement("button")
const goToNextSectionButton = document.createElement("button")

document.body.appendChild(goToPreviousSectionButton)
document.body.appendChild(goToNextSectionButton)

const sections = Array.from(document.querySelectorAll("section")).sort(
  (s1, s2) => {
    return s1.getBoundingClientRect().left - s2.getBoundingClientRect().left
  }
)

const getSectionInView = () => {
  const halfWidth = window.innerWidth / 2
  const index = sections.findIndex(
    section =>
      section.getBoundingClientRect().left <= halfWidth &&
      section.getBoundingClientRect().right > halfWidth
  )
  return index
}

const getNextSection = dir => {
  const sectionInViewIndex = getSectionInView()
  const nextIndex = sectionInViewIndex + dir
  const numSections = sections.length
  const nextSectionIndex =
    nextIndex < 0 || nextIndex >= numSections ? sectionInViewIndex : nextIndex
  return sections[nextSectionIndex]
}

const animateScroll = dir => {
  const from = container.scrollLeft
  const { left } = getNextSection(dir).getBoundingClientRect()
  return progress => (container.scrollLeft = from + progress * left)
}

goToPreviousSectionButton.addEventListener("click", () => {
  animate({
    easing: "out-quintic",
    change: animateScroll(-1)
  })
})

goToNextSectionButton.addEventListener("click", () => {
  animate({
    easing: "out-quintic",
    change: animateScroll(1)
  })
})

推荐阅读