乐趣区

关于程序员:Jerry的反省程序员不要轻易说出这个功能技术上无法实现

这是 Jerry 2020 年的第 81 篇文章,也是汪子熙公众号总共第 263 篇原创文章。

Jerry 之前的文章从医院到家,再重返 SAP 成都研究院,Jerry 还没死 提到,我手术后重返 SAP 成都研究院,退出了 Global 的 Spartacus 开发团队,开始从事 SAP Commerce Cloud 新一代 Storefront 的开发工作。文章 SAP Spartacus 简介,对 SAP Spartacus 做了一个概要介绍。

本文给大家分享 Jerry 上周解决一个 Spartacus issue 的经验。

原本 Jerry 也自夸是一位 SAP 全栈开发工程师——我能纯熟应用 SAP UI5,SAP Fiori Elements,SAP WebClient UI,SAP ABAP Webdynpro 进行全栈开发,并且深刻理解这些工具 / 框架的底层工作原理。

不过,当最近解决 Spartacus 的 Accessibility issue 时,我还是感觉本人的前端常识远远不够用。

满足 Accessibility(可拜访性)的利用,即利用以“所有人”为外围(包含某些残疾人),能在更广大的场景下毫无阻碍地被应用。

互联网的力量存在于它的普适性中,让包含残疾人在内的所有人都能拜访互联网, 是普适性中必不可少的一部分。
The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect.

Tim Berners-Lee
Inventor of the World Wide Web

Accessibility 也是 SAP Product Standard(产品规范)之一,在 SAP 产品从设计到开发,测试,直至最初公布的整个流程中,确保产品对 Accessibility 的良好反对,是每位 SAP 开发人员致力的指标之一。

Accessibility 听起来有点形象?SAP 产品为了满足 Accessibility,到底须要做什么具体的开发工作?确实,Accessibility 是一个比拟抽象的领域,比方 Jerry 目前工作的 Spartacus Accessibility, 落实到编程层面的实现,总共分为下图几类(Accessibility 缩写为 a11y). 而我上周手头上解决的一个 issue, 是对于键盘的可拜访性反对(Keyboard Accessibility). 简略来说,就是用户能用鼠标操作 Spartacus 实现的性能,用键盘也必须同样能实现。

“挪动 - 点击”的鼠标交互模式对于普通用户来说,是最为简便高效的网页定位形式。然而对于视觉存在阻碍的用户来说,用肉眼定位鼠标箭头的地位, 不是一件容易的事件。而对于某些存在肢体阻碍的用户来说,应用鼠标甚至都是一件十分艰难的事件(这一点 Jerry 刚刚被推出手术室后的头七天几乎深有体会)。

对这些因为某种原因无奈应用鼠标来拜访浏览器利用的非凡用户来说,如何将鼠标的“挪动 - 点击”的交互模式转换成其余更易操作的步骤呢?

咱们利用键盘的 tab 键,按秩序遍历页面上的元素。

通过这种形式,将本来用鼠标抉择页面元素的形式,切换成了用键盘 Tab 键来代替。

当按下 Tab 键遍历到某个元素时,该元素取得焦点 (focus), 触发 onfocus 事件。Jerry 解决的 issue, 如下图所示,问题症状就是 Spartacus Organization Unit List 这个列表的行我的项目,取得焦点时的轮廓线(outline) 显示不尽如人意,视觉效果须要改良。

列表行我的项目第一列的实现,是一个自定义复合控件(Composite Control, SAP UI5 也有相似概念,叫做 Reusable Control), 由一个 a 标签和一个 button 标签形成,其中 a 标签通过自定义管道 cxUrl 在页面渲染时动静生成一个 url, 指向该行我的项目对应的 Organization Unit 明细页面。当 a 标签持有 focus 时,鼠标点击或者回车键按下之后,跳转到 Org Unit 明细页面。

Button 标签联合自定义的 cx-icon 标签一起,二者独特实现一个三角箭头。点击后,会开展和收拢该 Org Unit 的子 Unit 列表。

Issue 形容的问题

当行我的项目复合控件内的 a 标签被 tab 键 focus 之后,因为 a 标签的 css 设置,它自身会显示被 focus 的轮廓线成果。同时,a 标签的父节点,tr 标签设置了伪类 focus-within, 其成果是,一旦 tr 有任意子节点失去 focus, tr 自身也会失去 focus.

如此一来,a 标签失去 focus 时,列表行我的项目就会同时呈现两套轮廓线,一套是标签 a focus 之后显示的 outline , 另一套是标签 tr 的 focus outline.

因为这个列表行我的项目一些另外的 bug, 这两套轮廓线的叠加显示,视觉效果不佳。更蹩脚的是,在不同宽度的屏幕下,a 标签本身的 focus 轮廓线还会有差别:只有当窄屏时,能力显示残缺的上下左右四条轮廓线。


我刚刚退出团队时,团队的开发经理给我调配了一位开发大佬,负责解答我开发过程中遇到的技术问题。据开发经理介绍,这位大佬是 Spartacus 的元老级人物,从 Spartacus 立项到当初最新的 3.0 版本始终参加其中。这位大佬第一次和我电话里相互介绍彼此时,给我学习 Spartacus 的倡议粗心就是,“遇到问题尽量本人多思考,多想方法,而不是马上就在 Slack 上
问我,这样你会成长很快”。


这正好和 Jerry 每当进入一个 SAP 新的畛域时的学习办法统一,我也没感觉什么不妥。

所以当我打算先把我 correction 的思路和大佬探讨时,大佬间接回复我一波三连击:

  • 我冀望的行为是 XXX
  • make it happen
  • show me the PR

我过后看到大佬提出的需要,第一反馈就是: 1 border when highlighting the row 这个需要,技术上无奈实现啊! 我过后的想法是,伪类 focus-within 不就是通过被润饰元素的子节点接管到 focus, 从而达到本身也被 focus 的成果吗?这意味着 Org Unit List 行我的项目内,只有有任意一个元素被 focus, 整个行我的项目必然有两套 focus 轮廓线呈现,而不是大佬要求的一套。所以,大佬这个需要技术上无奈实现啊。

于是,我向大佬表白了我的认识:我认为这个需要技术上无奈实现。

大佬没有回复我。

起初我把这个 issue 波及到的一些知识点列举了一下,通过 google 和 stackoverflow 逐个进行了学习:

  • scss 的工作原理
  • scss 里 % 和 & 的用法
  • scss 里 @minxin 的用法
  • scss 里 @include, @extend 的用法
  • pseudo class :focus 和:focus-within 的区别
  • tabindex 的应用办法
  • onfocus 和 onblur 的关联
  • css specificity 的含意和 calculation rule
  • a 标签能接管 focus 事件的前提条件
  • 页面元素 margin, padding 和 border 的区别,各自应用场景
  • 几种 css 选择器和优先级

学习完这些知识点之后,我立刻悔恨了,感觉当初不该对大佬说出“这个性能技术上无奈实现”这句傻话。事实上,要实现行我的项目 focus 时只显示一套 focus 轮廓线的需要,办法几乎太多太多了。

第一次尝试

我把 a 标签的 tabindex 设置成 -1, 这样 a 就不会收到 focus 了。a 标签的兄弟节点,button 标签收到 focus 时,其父节点即 tr 通过:focus-within,也收到 focus, 成果如下:

然而,因为 a 标签的 tabindex 为 -1, 意味着它不能再接管 focus 事件,所以回车之后无奈触发跳转到 unit 明细页面的操作了,这条路行不通。

第二次尝试

我想通过调整 a:focus 的 outline-offset 值,设法让其和 tr 的 focus 轮廓线齐全重合,这样 focus 事件产生时,视觉上讲,用户也只会看见一套轮廓线。

然而我察看了现有的 tr 轮廓线,发现有计算逻辑参加在外面,而 a 标签并没有。简略评估了一下,如果要让 a 标签在不同的屏幕尺寸下的轮廓线和 tr 标签的轮廓线始终保持重合,代价太大,得失相当,所以我放弃了。

第三次尝试

间接暗藏 a 标签的 focus 轮廓线。这样,技术上来说,尽管标签 a 失去 focus 时,它会和父标签 tr 同时被赋予各自的 focus 轮廓线,但前者的轮廓线被设置成暗藏,因而视觉效果上行我的项目只有一条轮廓线,这就满足了大佬的需要。

最初行我的项目失去 focus 时的轮廓线成果如下:

尽管通过这个 issue 我学到的 css 相干常识,在前端开发大佬们眼中不值一提,但这些的确是我以前不理解或者没有了解透彻的,因为以前始终做 SAP UI5 和 SAP WebClient UI 的应用层开发,99% 的状况下不会间接操作 css 和 scss.

我也非常感谢给我提出需要的开发大佬,在我贸然说出 ” 这个需要技术上无奈实现 ” 的时候,没有立刻怼我,而是抉择了间接忽视,这才给我发明了通过 google 和 stackoverflow 空虚本人的机会。

通过这个 issue 我的领会就是,程序员在本人尚不齐全相熟的畛域工作时,如果没有十足的把握,最好别贸然说出“这个性能技术上无奈实现”这种话,否则,后续可能会被打脸。

感激大家有急躁读完我工作中的产生的这件琐事,心愿对大家有一点点启发,感激浏览。

更多 Jerry 的原创文章,尽在:” 汪子熙 ”:

退出移动版