为WYSIWYG区块列表添加ARIA角色:判断逻辑失效原因咨询
问题
我有一个网站,其中「列表」内容区块已经给父级和子元素分配了正确的无障碍(Accessibility)角色。但列表也可以通过WYSIWYG区块添加,所以我写了下面的代码来确保这些列表也能获得正确的角色:
var lists = document.querySelectorAll("ol, ul"); for (var i = 0; i < lists.length; i++) { lists[i].setAttribute("role", "list"); } var lists = document.querySelectorAll("li"); for (var i = 0; i < lists.length; i++) { lists[i].setAttribute("role", "listitem"); }
为了提升代码效率,我想先检查有序或无序列表是否未设置role属性再执行上述代码,但写的判断逻辑无法正常工作,请问这是为什么?
if (document.querySelector("ol, ul") && ![role="list"]) { var lists = document.querySelectorAll("ol, ul"); for (var i = 0; i < lists.length; i++) { lists[i].setAttribute("role", "list"); } var lists = document.querySelectorAll("li"); for (var i = 0; i < lists.length; i++) { lists[i].setAttribute("role", "listitem"); } }
原因与修正方案
错误原因
- 语法错误:
![role="list"]是完全不符合JavaScript语法的写法,这不是有效的条件判断表达式,JavaScript无法识别,直接导致整个if逻辑失效。 - 逻辑偏差:
document.querySelector("ol, ul")仅返回页面中第一个匹配的列表元素,即便该元素已设置role="list",但后续还有未设置role的列表,判断会直接跳过所有处理,无法实现只处理未设置role列表的需求。 - 列表项处理逻辑错误:原代码只要进入
if就会给所有li添加role="listitem",但实际上只有未设置role的列表下的li才需要处理,否则会给已正确配置的li重复添加属性。
修正后的代码
直接在选择器中筛选出未设置role="list"的ol和ul,再针对性处理它们及其下属的li,既高效又精准:
// 仅选择未设置role="list"的ol和ul元素 var targetLists = document.querySelectorAll("ol:not([role='list']), ul:not([role='list'])"); for (var i = 0; i < targetLists.length; i++) { targetLists[i].setAttribute("role", "list"); // 找到当前列表下未设置role="listitem"的li元素 var listItems = targetLists[i].querySelectorAll("li:not([role='listitem'])"); for (var j = 0; j < listItems.length; j++) { listItems[j].setAttribute("role", "listitem"); } }
补充说明
- 使用
:not([role='list'])伪类选择器,在DOM查询阶段就过滤掉已设置正确role的元素,避免不必要的循环和重复属性设置。 - 针对每个目标列表,仅处理其下属的
li元素,不会影响其他已正确配置的列表项,逻辑更精准。
内容的提问来源于stack exchange,提问作者Johnny
相关产品推荐
相关产品推荐

