这是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的原创文章,尽在:“汪子熙”:

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

  1. [转]程序员最容易犯的几个技术上的错误

    请在评论里分享你的想法和经验,因为我们都需要从这些错误中吸取教训. 为钱而编程 如果你对编程不感兴趣,你的代码一定会写的很烂.结果不仅仅你的事业没有任何前途,你的团队也会因此而痛苦不堪. 缺乏基本的能 ...

  2. 美团大咖:程序员35岁前应做好的技术积累

    刘丁 读完需要 26 分钟 速读仅需 9 分钟 引言 古人云:"活到老,学到老."互联网算是最辛苦的行业之一,"加班"对工程师来说已是"家常便饭&qu ...

  3. 禁毒学、油画、乌尔都语……字节跳动程序员的专业有多奇特丨技术同学大数据报告...

    在字节跳动,有超过两万名技术人才,他们分布在 11 个国家的 32 座城市里. 从 18 岁的实习生到 60 岁的专家,这群字节跳动技术人有着不同的经历和故事. 有人写 Go,有人写 Python,不 ...

  4. 程序员怎样才能写出一篇好的技术文章

    来源:http://droidyue.com/blog/2016/06/19/how-to-write-an-awesome-post/ 首先,这算是一篇回答知乎问题 程序员怎样才能写出一篇好的博客或 ...

  5. 为什么中国这么多高薪程序员,开发不出Java, Typescript, Python, Rust, Node.js这些基础设施?...

    近日,有人在网上问了这个问题,引起了网友热议: 为什么中国这么多高薪程序员,开发不出Java,Typescript, Python, Rust, Node.js这些基础设施? 对这个问题,大家从不同角 ...

  6. 程序员的灯下黑:重知识轻技术(转)

    为什么80%的码农都做不了架构师?>>>    程序员的灯下黑:重知识轻技术(转) 电视<雍正王朝>讲了这么一个故事:大将军年羹尧奉命到青海平叛,清军因路途遥远,军耗巨大 ...

  7. 【全国卷】程序员的自主命题!一本正经聊技术、代码,以及。。。。。。

    IT168最近举办了一个"程序员高考",链接:http://bbs.chinaunix.net/thread-4262987-1-1.html 我给每个话题写了一篇作文,任意两篇字 ...

  8. 程序员如何提高自己的逻辑思维和技术水平

    2019独角兽企业重金招聘Python工程师标准>>> 版权声明:本文为北京尚学堂原创文章,未经允许不得转载.​ 菜鸟程序员如何提高自己的逻辑思维和技术水平 1. 学习一门脚本语言 ...

  9. 菜鸟程序员如何才能快速提高自己的技术

    导语:很久没有这么悠闲的在家撸一篇文章了,最近也在思考怎样才能写一些对程序员帮助非常大的文章,怎样去运营好我们这个移动开发者聚集地的公众号:非著名程序员.当初弄这个公众号的本意就是为广大的开发者提供各 ...

最新文章

  1. java 数组 列表_用Java将列表转换为数组
  2. Hibernate框架的配置
  3. 如何在一个页面添加多个不同的kindeditor编辑器
  4. 前端学习(530):等分布局得间距方案第二种方式
  5. ABP框架使用 Swagger
  6. 切换分支 如何判断 是否完成_如何判断展览公司是否专业?
  7. java除号_Java的运算符
  8. 【论文写作】JSP旅游网如何写总体设计
  9. Python海龟turtle画图常见画图代码大全
  10. 学习 TList 类的实现[1]
  11. 【优化预测】基于matlab遗传算法优化极限学习机ELM预测【含Matlab源码 1673期】
  12. java acr122 读取数据_acr122读写器软件下载
  13. 图论(九)——图连通度
  14. 就在明天 用友企业数智化财务峰会落地广州,聚焦实现业财合一新价值
  15. spark开发及调优
  16. 成都大数据语言培训:如何提高数据分析能力
  17. JAVA记录从键盘输入的正数和负数的个数(0结束)
  18. 体系结构第1章—基本概念
  19. 社区发现-Fast Unfolding
  20. 墨者学院-SQL注入漏洞测试(布尔盲注)

热门文章

  1. javascript学习笔记(一)-廖雪峰教程
  2. CSS/Compass修改placeholder的文字样式
  3. 《D3.js数据可视化实战手册》—— 1.1 简介
  4. 纯 as3 项目中引用 fl 包下的类
  5. 窝里斗,只给微软看笑话
  6. asp.net ajax1.0基础回顾(六):调用ASPX页面方法
  7. 使用UTL_FILE在oracle中读写文本数据
  8. Internet 网络协议族
  9. 分布式版本控制工具Git
  10. sql中的exsits和not exsits