蜂蛰伤论坛

首页 » 常识 » 问答 » 前端技术资讯关于导航卷轴的未来
TUhjnbcbe - 2024/5/1 21:31:00
白癜风公益献礼 https://m.39.net/pf/a_5779537.html

你一直想知道的所有关于实施滚动,但不敢问的问题。我们有滚动的现代web规范来带您了解最新走马观花的CSS和JavaScript特性,使导航在单个页面光滑,美丽并且占有更少的资源。

大多数网页都不适合单一屏幕,所以它的能力卷轴信息是由所有用户都给予的。对于前端开发人员和用户体验设计师来说,实现滚动体验,在浏览器上运行良好,很好地适应了设计,并且仍然表现良好,可能是一个挑战。随着web标准的发展速度比以往任何时候都快,编码实践往往落后于它。阅读一下,重新查看一些常见的角点,以便滚动和检查您使用的解决方案是否已经被一些更优雅的东西所取代。

一个消失滚动条的奇怪案例

在过去的三十年间,滚动条的外观不断变化,响应设计趋势。颜色、阴影、箭头形状、边框半径-界面设计师尝试所有的东西。下面是windows上的旅行方式:

windows中的Scrollbars

,苹果的界面设计师们从ios中获取线索,最终结束了所有“美化”滚动条的尝试。无处不在的设计元素刚刚从所有的mac上消失了。它不再在静态视图中使用任何空间,只有当用户开始滚动时才会出现。

在mac上的

滚动条的平静死亡从来没有被苹果的民间哀悼。用户习惯于滚动方式在iphone和ipad上进行,很快就接受了改变,大多数开发人员和设计师都认为“好摆脱!”对于滚动条宽度来说,计算总是很繁琐的。

然而,我们仍然生活在一个具有多个操作系统和浏览器实现的世界中。如果您为web开发,就像我们一样,您不能仅仅将“滚动条问题”推到一边。

我们将向您展示一些技巧,可以让您的用户更愉快地滚动体验。

隐藏和滚动

让我们来看看一个典型的模态窗口示例。当打开时,页面的主要内容应该停止滚动。在css中有一个快速的方法:

body{overflow:hidden;}

但是这个代码导致了一个令人不快的神经过敏效果,被捕获到下面。

小心红色箭头

在本例中,为了演示(因此我们可以与windows用户的体验相关联),mac上的滚动条被迫保持在系统首选项中(并且可以与windows用户的体验相关联)。

我们如何解决这个问题?如果我们知道滚动条的宽度,那么每次打开模式窗口时,我们可以在主页右侧添加偏移量。

但是宽度并不容易猜测,因为不同操作系统和浏览器不同的方式是mac是最一致的(15px,不管应用程序),windows让开发者疯狂:

这里有一个像素,一个像素…

注意,这些度量只涉及到电流windows下的浏览器版本。在早期版本中,情况有所不同,没有人知道将来会发生什么变化。

您可以通过使用javascript来动态计算滚动条宽度,而不是猜测:

constouter=document.createElement(div);constinner=document.createElement(div);outer.style.overflow=scroll;document.body.appendChild(outer);outer.appendChild(inner);constscrollbarWidth=outer.offsetWidth-inner.offsetWidth;document.body.removeChild(outer);

这只是七行代码,但是这些代码行与dom交互。除非绝对必要,避免Dom操作更好。

解决这个问题的另一种方法是让滚动条在模态后面保持可见。下面是如何用纯css来实现它:

html{overflow-y:scroll;}

“跳过模态问题”解决了,但你却被困在残废滚动条,在你的完美设计中可能是视觉上的疼痛。

我们认为,一个更好的解决方案是完全删除滚动条。这也可以用样式来完成。该方法不正确复制macos行为,因为滚动条没有出现滚动:它始终保持隐藏,但页面保持可滚动。对于chrome、safari和opera,您可以使用这个css:

.container::-webkit-scrollbar{display:none;}

对于internetexplorer和edge:

.container{-ms-overflow-style:none;}

不幸的是,火狐浏览器你已经摆脱了运气:没有办法摆脱滚动条。

正如你所看到的,没有银色子弹。我们所描述的每一种方法都有其优点和缺点。挑选一个适合你的项目的人。

为了外表而战

让我们承认:一些操作系统中默认滚动条实现并不是非常漂亮。有些设计师喜欢完全控制他们的应用程序的外观和感觉,而不是让任何事情都有机会。有数百GitHub存储库使用javascript中的自定义滚动条实现完全替换系统默认值。

但是如果您想要定制现有浏览器滚动条呢?没有通用api,每个供应商都会让您做不同的事情。

internetexplorer允许您在5.5版本之后对滚动条的外观进行混乱,但是您只能更改颜色。下面是如何重新绘制一个“拇指”(你拖动的部分)和箭头:

body{scrollbar-face-color:blue;}

但是,使用颜色的游戏很少足以完成用户体验。WebKit开发人员理解并提出他们自己的造型方式已经在了。下面是您如何使用-webkit供应商前缀复制任何WebKit浏览器中的macos滚动条:

::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-thumb{background-color:#c1c1c1;border-radius:4px;}

这些调整是支持在桌面chrome,safari,opera,甚至移动在uc浏览器或三星互联网上。边缘计划也要实施但三年后,它仍处于一个中等优先地位的积压之中。

当谈到定制滚动条时,mozillafoundation是一个绝对冠军,忽略设计者的需求。打开firefox中滚动条的一个功能请求打开17年前在千年之初。仅仅几个月前,jeff格里菲斯(mozillafirefox浏览器的总监)终于用一个答案来保证线程:

“除非有实际规范,除非平台团队中的某个人感兴趣地在一个一种后面原型设计,但我对做任何事情都毫无兴趣。”

为了公平起见,从w3c的观点来看,WebKit方法虽然支持很好,但它却并不存在。a现有草案对于css,Scrollbars规范从ie中获取提示:定制停止在颜色上。

战斗继续下去,问题打开请求支持WebKit定制。如果你想要尝试影响css工作组-现在是时候加入讨论了。也许,问题不是首要的问题,但是标准化的支持可以使许多前端开发人员和设计师更容易生活。

平滑算子

涉及滚动的最常见任务就是导航到登陆页。通常,它是用锚连接完成的。你只需要知道一个元素的id:

ahref=#sectionSection/a

单击该链接将导致跳对于这个部分,通常用户体验设计师会坚持某种动画使滚动顺畅。有太多的在GitHub上准备好的解决方案使用了或多或少的javascript,但是现在只有一行代码可以实现相同的操作。从最近开始,Element.scrollIntoView()从在选择选项对象用behavior键,使平滑滚动出框:

elem.scrollIntoView({behavior:smooth});

但是对于选项的浏览器支持仍然存在。相当有限而且它还是个剧本。如果可能的话,应该避免额外的脚本。

幸运的是,有一个全新的css属性(仍在工作草稿)中,可以使用一行代码更改整个页面的滚动行为:

html{scroll-behavior:smooth;}

以下是结果:

从一节跳到另一节

平滑滚动

你可以自己玩这个财产这是个codepen。写到这篇文章中,scroll-behavior只有chrome、firefox和opera支持,但是我们希望它会被普遍采用,因为解决css平滑滚动问题更加优雅,并且它更适合于“渐进增强“心态。

坚持css

另一个常见任务是动态地定位一个元素,根据滚动方向,著名的“粘性”效果。

粘性元素

在过去,一个“粘性”实现需要编写一个复杂的滚动处理程序来计算元素的大小。试图优化处理程序导致了“粘贴”和“unsticking”的微妙延迟,导致了紧张。javascript实现在性能方面也落后于此,尤其是在Element.getBoundingClientRect()用过.

不久前,position:sticky属性在css中实现。它允许通过指示偏移量来实现所期望的效果:

.element{position:sticky;top:50px;}

其余的将以最有效的方式由浏览器来处理。你可以在里面测试它这是个codepen。写这篇文章时position:sticky几乎是普遍支持(包括移动浏览器),所以如果您仍然在处理javascript中的问题-现在是时候坚持纯css了。

全油门

从浏览器的角度来看,滚动是一个事件因此,在javascript中,您使用标准处理它addEventListener:

window.addEventListener(scroll,()={constscrollTop=window.scrollY;/*doSomethingwithscrollTop*/});

但是人们往往会滚动很多,如果事件频繁地被发射(并且它在每个像素滚动上都被发射)-它不可避免地会导致性能问题。您可以使用称为浏览器的技术来使浏览器的工作变得更容易节流:

window.addEventListener(scroll,throttle(()={constscrollTop=window.scrollY;/*doSomethingwithscrollTop*/}));

然后,您需要定义一个throttle函数将围绕监听器函数进行包装,并将通过禁止其每次发射超过一次的时间来“按需间隔”速度执行它:

functionthrottle(action,wait=){lettime=Date.now();returnfunction(){if((time+wait-Date.now())0){action();time=Date.now();}}}

为了使事情变得更顺畅,你可以控制一下节流withwindow.requestAnimationFrame():

functionthrottle(action){letisRunning=false;returnfunction(){if(isRunning)return;isRunning=true;window.requestAnimationFrame(()={action();isRunning=false;});}}

当然,您可以自由使用现成的实现就像n.Lodash。检查这是个codepen查看上面描述的解决方案与_.throttle从Lodash。

您选择哪个并不重要-记住要以某种方式优化您的滚动事件处理程序。

停留在视窗中

技巧懒惰加载用于图像或无限滚动需要您来确定元素是否出现在视图中。这也是在事件侦听器内部完成的,其中最常见的解决方案是Element.getBoundingClientRect():

window.addEventListener(scroll,()={constrect=elem.getBoundingClientRect();constinViewport=rect.bottom0rect.right0rect.leftwindow.innerWidthrect.topwindow.innerHeight;});

这个代码的问题是每个调用getBoundingClientRect导致a回流而且总体表现也会受到打击。在事件处理程序内部调用这些调用时,更糟糕的是,即使在这种情况下节流也没有什么帮助。

该问题于进行处理,其中介绍了交点观测器api。它允许跟踪元素与其祖先之间的交集,而不一定是浏览器的视图。此外,即使元素只有一个元素,也可以选择触发回调。部分在视图中出现,甚至是单个像素:

constobserver=newIntersectionObserver(callback,options);observer.observe(element);

这个api是广泛支持但是有些浏览器可能需要n.polyfill。尽管如此,即使是一个一种,也是迄今为止最好的解决方案。

不要太远

如果您必须实现可滚动的弹出或下拉,则必须注意到滚动链问题:当您滚动到元素的末尾之后,整个页面开始移动。

滚动链接可视化

您可以通过操作overflow页面的属性或通过截取元素上的滚动条,并取消每当到达元素边界时滚动事件。

如果选择javascript,请确保不要处理“滚动”,而是“车轮”每当用户用鼠标滚轮或触摸板滚动页面时触发的事件:

functionhandleOverscroll(event){constdelta=-event.deltaY;if(delta0elem.offsetHeight-deltaelem.scrollHeight-elem.scrollTop){elem.scrollTop=elem.scrollHeight;event.preventDefault();returnfalse;}if(deltaelem.scrollTop){elem.scrollTop=0;event.preventDefault();returnfalse;}returntrue;}

不幸的是,这个解决方案并不十分可靠。同时,它也会对性能产生负面影响。

对于移动设备来说,overscroll尤其是一个威胁。罗兰·Brichter在他的Tweetie应用程序中,已经创建了一个“刷新”手势,这个技巧已经让用户体验社区受到风暴:包括twitter和facebook在内的所有主要玩家都采用了这种方式。

当同一个功能进入安卓浏览器时出现了问题,这对每个在web应用程序中实现“拉刷新”的人来说变得非常麻烦:如果你把页面拉下来,它会导致完整的刷新而不是加载更多的帖子。

css来救了新财产:overscroll-behavior。它允许控制到达滚动边界的行为,既处理了刷新和滚动链接,也可以使用操作系统特有的特效:android的“发光”和苹果的“橡皮筋”。

现在,上面gif显示的问题可以在chrome、opera或者firefox中解决,其中只有一行代码:

.element{overscroll-behavior:contain;}

要公平起见,internetexplorer和edge实现-ms-scroll-chaining财产它控制滚动链,但它不会处理所有的情况。幸运的是,根据这条线,overscroll-behavior微软浏览器的实现正在进行之中。

最后的触摸

滚动在基于触摸的接口是一个很大的主题,它有自己的文章。然而,这里值得提及,因为很多开发人员往往忽略了可能性。

你经常看到周围的人在智能手机屏幕上来回移动手指吗?没错,这一切都发生了,而且大多数人在阅读这篇文章时也会这么做。

当你把手指移到屏幕上时,你会期望有一件事:流畅、不间断地移动内容。

“动量”或“惯性”滚动,先驱者以及专利苹果很快就成为了标准用户体验,现在它被连接到我们大脑中巴甫洛夫时尚。

但是也许您已经注意到,虽然移动操作系统对整个页面的滚动都是由移动操作系统处理的,但是当您尝试滚动时它会消失。元素内部在那页上。对于移动用户来说,潜意识里会有一些惰性,这会让人感到沮丧。

这是一个css解决方案,但它更像是一个黑客:

.element{-webkit-overflow-scrolling:touch;}

为什么它是个黑客?首先,它只适用于供应商前缀。其次,它只适用于触摸设备。最后,如果浏览器不支持这个功能,那么我们应该把它放在这个位置上吗?无论如何,有一个解决方案,并且您可以自由使用它。

在触摸设备上开发滚动体验时要考虑的另一个要点是浏览器在处理时的性能。touchstart或touchmove事件。这个问题完全被描述了这里。简而言之,现代浏览器虽然知道如何处理单独线程中的平滑滚动,但仍需等待,有时高达ms,用于处理这些事件的处理程序,以便准备好。取消滚动的滚动Event.preventDefault().

即使是一个从不取消任何东西的空侦听器,也会对性能产生显著的负面影响,因为浏览器仍然期望preventDefault被称为。

要显式地告诉浏览器它不应该期望取消事件,请使用有点模糊的特征存在于WHATWG米活标准。相会被动事件侦听器享受到相当多的慷慨支持:想法是传递一个可选对象参数给监听器,该侦听器告诉浏览器发生的事件永远不会被取消。呼叫preventDefault在这样的处理程序中不会做任何事情:

element.addEventListener(touchstart,e={/*doSomething*/},{passive:true});

还有一个n.polyfill以弥补不受支持的浏览器。这一改进的效果在视频.

如果它没有破裂,为什么要修复它?

在现代web中,依赖定制javascript实现所有客户端的相同行为不再是合理的:“跨浏览器兼容性”的整个概念已经成为过去,更多的css属性和Dom方法将其应用到标准浏览器实现中。

我们认为,渐进增强在您的web项目中实现非平凡滚动时,最好的方法是遵循。

确保您可以提供尽可能少、但普遍支持的用户体验,然后考虑到现代浏览器功能。

必要时,使用polyfills,因为它们不会创建依赖项,并且一旦必要的支持已经到达,就可以轻松地删除。

六个月前,当本文仅仅是一个想法时,我们所描述的一些属性仅在几个浏览器中引入。到出版时,它们几乎得到普遍支持。

也许现在,当您滚动本文时,另一个浏览器已经为一个属性提供了支持,这样可以使您的生活变得更加轻松,并且您的bundle大小也会更小。

1
查看完整版本: 前端技术资讯关于导航卷轴的未来