ok~_~ok 2022-01-26 19:23 采纳率: 80%
浏览 63
已结题

利用Math.ceil等近似方法是否会影响该滚动动画的精确性?

完整代码及动画运行效果:https://codepen.io/TristanBLG/pen/xWvByO?editors=1010

代码中实现了滚动页面至相应元素的功能,有疑问的地方在于代码利用Math.ceilMath.round做了一些近似的处理,这是否会影响到页面滚动到对应元素的精确性?涉及到小数总是难以判断.
比如使用Math.ceil处理后会比原始值大0.x,如果要求动画精确一点,这0.x是这个例子中不需要考虑的吗?
为什么有些地方用Math.ceil?而有些地方又用了Math.round?

做了近似处理的地方:

window.scroll(0, Math.ceil((time * (destinationOffsetToScroll - start)) + start))
if(time >= 1 || Math.round(window.pageYOffset) === destinationOffsetToScroll) {}

完整JavaScript代码:

const scrollTo = function({target, duration = 200, callback} = {}){
  if(!target){
    console.error('scrollTo() => You must specify a target.')
    return false
  }
  const targetHref                  = target.getAttribute('href').replace( /^#/ , '')
  const destination                 = document.getElementById(targetHref)
  const start                       = window.pageYOffset
  const startTime                   = 'now' in window.performance ? performance.now() : new Date().getTime()
  const documentHeight              = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight)
  const windowHeight                = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[0].clientHeight
  const destinationOffset           = typeof destination === 'number' ? destination : destination.offsetTop
  const destinationOffsetToScroll   = Math.round(documentHeight - destinationOffset < windowHeight ? documentHeight - windowHeight : destinationOffset)

  if('requestAnimationFrame' in window === false) {
      window.scroll(0, destinationOffsetToScroll)
      if(callback) {
          callback()
      }
      return
  }
  
  const scroll = function() {
    const now   = 'now' in window.performance ? performance.now() : new Date().getTime()
    const time  = Math.min(1, ((now - startTime) / duration))
    
    window.scroll(0, Math.ceil((time * (destinationOffsetToScroll - start)) + start))
    
    if(time >= 1 || Math.round(window.pageYOffset) === destinationOffsetToScroll) {
      if(callback) {
        callback()
      }
      return
    }

    requestAnimationFrame(scroll)
  }

  requestAnimationFrame(scroll)
};

const navLink = Array.from(document.querySelectorAll('[href^="#"]'))
  navLink.forEach(el => {
    el.addEventListener('click', function(ev) {
      ev.preventDefault()
      ev.stopPropagation()
      scrollTo({
        duration: 300,
        target: ev.target
      });
    })
})
  • 写回答

2条回答 默认 最新

  • CSDN专家-showbo 2022-01-26 21:37
    关注

    设置scrollTop包含小数实际会调用Math.floor,设置不了小数,所以多少会有点定位不准,0.几px是少不了

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 2月4日
  • 已采纳回答 1月27日
  • 创建了问题 1月26日

悬赏问题

  • ¥30 雷达辐射源信号参考模型
  • ¥15 html+css+js如何实现这样子的效果?
  • ¥15 STM32单片机自主设计
  • ¥15 如何在node.js中或者java中给wav格式的音频编码成sil格式呢
  • ¥15 不小心不正规的开发公司导致不给我们y码,
  • ¥15 我的代码无法在vc++中运行呀,错误很多
  • ¥50 求一个win系统下运行的可自动抓取arm64架构deb安装包和其依赖包的软件。
  • ¥60 fail to initialize keyboard hotkeys through kernel.0000000000
  • ¥30 ppOCRLabel导出识别结果失败
  • ¥15 Centos7 / PETGEM