JavaScript、vue中控制滚动条位置(以及安卓手机中遇到的坑)

最近做了一个需求的,其中有一个效果是点击按钮将表单滚动到可视区域,这本来是很常见的效果。我们有很多种方案去实现。
一、 scrollTo、scroll or scrollBy
image.png
这显示不支持safari on ios ,但是我的手机版本是13.3.1的safari可以运行没有问题,但是安卓手机完全无效果

1
2
3
4
5
6
7
8
9
window.scrollTo({
top: 1000,
left: 100,
behavior: 'smooth'
});
document.body.scrollTo({
top: 1000,
behavior: 'smooth'
});

vue中可以根据ref来操作dom

1
2
3
4
this.$refs.xxx.$el.scrollTo({
top: 1000,
behavior: 'smooth'
});
1
2
3
4
5
6
window.scroll({
top: 100,
left: 100,
behavior: 'smooth'
});
document.body.scrollBy(0, 1000);

二、scrollTop 获取当前页面的滚动条纵坐标位置去改变其值

  • 对于没有doctype声明的页面里可以使用 document.body.scrollTop 来获取 scrollTop高度 ;
  • 对于有doctype声明的页面则可以使用 document.documentElement.scrollTop; Safari
  • safari 比较特别,有自己获取scrollTop的函数 : window.pageYOffset ; Firefox
  • 火狐等等相对标准些的浏览器就省心多了,直接用 document.documentElement.scrollTop ;

浏览器和ios都可以生效,但是安卓手机手机完全无效果,测试了一下,安卓手机设置完scrollTop再去console出scrollTop的值,发现并没有赋值成功

1
document.body.scrollTop = document.documentElement.scrollTop = window.pageYOffset = 1000;

三、scrollIntoView 与 scrollIntoViewIfNeeded API (安卓、ios手机支持,浏览器测试结果看来也没问题)
Element.scrollIntoView()方法让当前的元素滚动到浏览器窗口的可视区域内。这是一个实验中的功能
image.png

1
2
3
4
5
element.scrollIntoView(true);
或者
element.scrollIntoView({behavior: "instant", block: "start", inline: "nearest"});
vue中
this.$refs.xxxx.$el.scrollIntoView();

Element. scrollIntoViewIfNeeded()
如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。 此方法是标准的Element.scrollIntoView()方法的专有变体。非标准 该特性是非标准的,请尽量不要在生产环境中使用它!
image.png

1
element. scrollIntoViewIfNeeded(true);

vue中根据ref来操作dom

1
this.$refs.xxxx.$el. scrollIntoViewIfNeeded();

Window.pageYOffset

image.png

监听,取消监听滚动事件
注意scroll监听的匿名事件是不可以取消监听事件的,我想要的是页面中所有需要曝光的地方曝光结束后,取消监听事件
可以参照埋点之眼球曝光

1
2
3
4
5
window.addEventListener('scroll', this.handleScroll);
window.removeEventListener('scroll', this.handleScroll);
const handleScroll = () => {
console.log(111111)
}