最近有一个bug真正困扰了我,就是JavaScript在网络中浏览一个页面的方式。一些简单却常见的,比如用户跟网页的交互被无缘无故延迟了这类事情,或者在本文中的例子—— 链接没有像链接那样工作。
对此,我也时常感到愧疚,所以,我写下这片博文,目的是希望能唤醒我自己,不再做这类的事情。
点击事件…
一切要从一个Click单击属性开始,在那之后事情开始变得越来越不顺利。最终,我决定接管原生浏览器对访问者点击DOM中特定元素的处理方式,这大概是一个很好的理由。
要做这个事情,可能我需要在后台放置一个API请求,用来更新某部分用户界面,或者 我可以在发请求之前做一些校验。
我用Next.js做了很多客户端的工作,我喜欢它是因为它支持服务端渲染,并且开箱即用,无需繁琐的配置,这很棒。
鉴于Next路由工作原理,我经常需要重写浏览器原生的点击事件,以便我可以跑后续的客户端渲染导航。通过这种方法,可以从预获取的代码(布局)中收益,也能有更好更快的用户体验,更能让网页访问者在随便点点的过程中减少往返请求时间和请求数据,无需忍受等待时长。
我搞砸了
这里是我的(React)代码:
上面这个组件像预期那样工作。组件做的事情很简单——访问者点击了card组件,然后组件加载了一个新的路由(文件在./pages/_single.js路径),传递了查询参数id=nnn。
这个组件有2处有问题。第1处应该很容易(我希望)看出来,第2处稍微不容易发现一些。
“不完全”的服务端渲染
最近我遇到这类的站点越来越频繁了。为了达到对SEO友好以及性能方面的目的,它们会使用服务端渲染技术,因为这样的话网页就不用依赖JavaScript去加载。除非当网页加载完毕,需要依靠JavaScript去真正地响应用户交互行为的时候——比如说点击。
以我上面的代码为例,如果网络连接还没完全好(比如移动端连接),可点击的元素(card组件)已经加载了,但是并没有任何处理点击的方法,就像一个锚点元素一样。
那么现在我有一个经验之谈:如果页面中有一个onClick,那么在组件周边最好得有一个锚点。
话说回来,代码中的第2处问题你们发现了吗?
比浏览器懂得更多
有了JavaScript我可以实现一些很酷很炫的事情。难过的是小部分很炫的事情一开始接管了原生浏览器的功能,到最后并没有放权,并且一些情况下,还会意外地将这些原生功能抛得远远的。
在上面这个特殊的例子里,我网站的访问者没有任何办法能点击那些我本意想让他们点击的组件,这让我感到相当冒昧。
点击的时候按下Shift键会发生什么?
点击的时候按下Command键(或者Control键)会发生什么?
答案是这两个动作都不起作用。它应该在新窗口或者新标签页分别打开,这是我的网页访问者预期发生的动作,那么为什么我要决定他们不能这么做呢?答案很简单:我没有思考。没有任何东西让我网站的访问者感到困惑,或者更坏的是,让他们感到厌烦。
修复的话简单地很,就一行代码就能搞定,让我们来改一下:
新的经验法则
任何时候,我为一个组件添加onClick方法,我都会确认一下是否真的存在锚点去处理预想的动作,我也会确保原生浏览器会按照预想的那样处理修饰符。很多网站不允许我对点击事件使用修饰符——我不想加入他们惹怒站点访问者的行列。
英文原文:https://remysharp.com/2019/04/04/how-i-failed-the-a
译者:疯禽忘肿