You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

scroll-behavior属性在真机手机上无平滑滚动效果问题求助

问题:scroll-behavior: smooth在Chrome手机模拟生效,但实际手机设备不生效

我在CSS中给html, body添加了scroll-behavior: smooth属性,在Google Chrome的手机模拟调试工具中可以实现平滑滚动效果;但在实际手机设备中加载网站时,无法呈现滑动过渡效果。

相关代码如下:

JavaScript代码

function scrollToSection(event) { 
  if (supportsSmoothScrolling()) { 
    return; 
  } 
  event.preventDefault(); 
  const scrollToElem = document.getElementById("section"); 
  SmoothVerticalScrolling(scrollToElem, 300, "top"); 
}
function supportsSmoothScrolling() { 
  const body = document.body; 
  const scrollSave = body.style.scrollBehavior; 
  body.style.scrollBehavior = 'smooth'; 
  const hasSmooth = getComputedStyle(body).scrollBehavior === 'smooth'; 
  body.style.scrollBehavior = scrollSave; 
  return hasSmooth; 
};
function SmoothVerticalScrolling(element, time, position) { 
  var eTop = element.getBoundingClientRect().top; 
  var eAmt = eTop / 100; 
  var curTime = 0; 
  while (curTime <= time) { 
    window.setTimeout(SVS_B, curTime, eAmt, position); 
    curTime += time / 100; 
  } 
}
function SVS_B(eAmt, position) { 
  if (position == "center" || position == "") 
    window.scrollBy(0, eAmt / 2); 
  if (position == "top") 
    window.scrollBy(0, eAmt); 
}

CSS代码

html, body { 
  scroll-behavior: smooth; 
  overflow-y: scroll; 
}

HTML代码

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="container-fluid h-100 nopadding">
<div class="row h-100 nopadding">
<div class="col-lg-8 black nopadding text-center d-flex flex-column justify-content-center">
<a onclick="scrollToSection(event)" href="#more" class="more">Here is the button</a>
</div>
<div id="more" class="col-lg-4 white nopadding text-center d-flex flex-column align-self-center justify-content-center">
Here is the section
</div>
</div>
</div>

注:我未添加全部页面元素,代码中的箭头代表锚点标签。


可能的原因及解决办法

1. 原生平滑滚动的检测逻辑有误

你写的supportsSmoothScrolling函数检测的是body元素的scrollBehavior,但实际上浏览器的平滑滚动是作用在根容器html(document.documentElement)上的,这会导致检测结果不准确——明明手机浏览器支持原生平滑滚动,却误判为不支持,或者反过来。

修改后的检测函数:

function supportsSmoothScrolling() { 
  const html = document.documentElement; 
  const scrollSave = html.style.scrollBehavior; 
  html.style.scrollBehavior = 'smooth'; 
  const hasSmooth = getComputedStyle(html).scrollBehavior === 'smooth'; 
  html.style.scrollBehavior = scrollSave; 
  return hasSmooth; 
};

2. 滚动容器设置冲突

你同时给html和body设置了overflow-y: scroll,部分移动浏览器会因此混淆实际的滚动容器,导致scroll-behavior无法生效。

调整CSS:

html { 
  scroll-behavior: smooth; 
  overflow-y: scroll; 
}
body {
  overflow-y: auto; /* 让body自适应内容,避免双重滚动容器 */
}

3. 代码里的笔误(关键问题!)

你的滚动函数里写的是document.getElementById("section"),但实际要滚动到的元素ID是more,这会导致自定义滚动逻辑找不到目标元素,自然没有任何滚动效果。

修正笔误:

const scrollToElem = document.getElementById("more"); 

4. 锚点链接的默认行为干扰

移动浏览器中,<a>标签的默认锚点跳转可能会优先执行,哪怕你调用了event.preventDefault()。可以直接禁用默认的锚点行为,或者强化阻止逻辑:

方案一:修改href属性

<a onclick="scrollToSection(event)" href="javascript:void(0)" class="more">Here is the button</a>

方案二:增强阻止逻辑+原生滚动触发
如果检测到支持原生平滑滚动,直接用window.scrollTo触发原生效果,比依赖锚点更可靠:

function scrollToSection(event) { 
  event.preventDefault();
  event.stopPropagation();
  const targetElem = document.getElementById("more");
  if (supportsSmoothScrolling()) { 
    window.scrollTo({
      top: targetElem.offsetTop,
      behavior: 'smooth'
    });
    return; 
  } 
  SmoothVerticalScrolling(targetElem, 300, "top"); 
}

5. 自定义滚动函数的兼容性问题

你用setTimeout循环实现的自定义滚动,在移动设备上可能因为浏览器的定时器节流、性能问题导致效果卡顿或失效。建议改用更适合浏览器动画的requestAnimationFrame:

优化后的自定义滚动函数:

function SmoothVerticalScrolling(element, duration, position) {
  const targetTop = element.getBoundingClientRect().top + window.pageYOffset;
  const startTop = window.pageYOffset;
  const distance = targetTop - startTop;
  let startTime = null;

  function animation(currentTime) {
    if (startTime === null) startTime = currentTime;
    const timeElapsed = currentTime - startTime;
    const progress = Math.min(timeElapsed / duration, 1);
    // 加入缓动函数,让滚动更自然
    const easeProgress = progress < 0.5 
      ? 2 * progress * progress 
      : 1 - Math.pow(-2 * progress + 2, 2) / 2;
    window.scrollTo(0, startTop + distance * easeProgress);
    if (timeElapsed < duration) {
      requestAnimationFrame(animation);
    }
  }

  requestAnimationFrame(animation);
}

内容的提问来源于stack exchange,提问作者Bonsaï

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 03:52:42