DOM
参考: https://www.w3.org/TR/DOM-Level-3-Events/#event-flow
DOM事件流分为三个阶段, 按顺序触发相应的事件监听器:
- 1.捕获阶段(capture phase)
从最外层的父元素开始发出事件, 层层递进直至目标(真正发出事件的元素).
在捕获阶段可以先于发出事件的元素(目标)进行操作,
需要在注册事件监听器时设置useCapture或{ capture: true }(默认为false). - 2.目标阶段(target phase)
调用目标元素直接相关的事件监听器, 这是 DOM 事件流里最不反常识的部分.
在该阶段可以调用stopPropagation()阻止事件冒泡. - 3.冒泡阶段(bubble phase)
从目标元素向外开始发出事件, 层层递进直至最外层的父元素.
如果目标阶段的元素阻止事件冒泡, 则该阶段不会发生.
之所以同时存在捕获阶段和冒泡阶段, 是因为早期浏览器的事件传播没有标准化: Netscape使用捕获, IE使用冒泡.
该属性用于检查事件是否允许冒泡, 其值为
false 时会跳过事件的冒泡阶段(buble phase)该元素指当前事件监听器绑定的元素.
该属性只在事件处理阶段可用, 如果在事件处理阶段以后查看, 属性值将变成
该属性只在事件处理阶段可用, 如果在事件处理阶段以后查看, 属性值将变成
null.在目标阶段与
在捕获阶段和冒泡阶段与
target 相同.在捕获阶段和冒泡阶段与
target 不同.该属性指真正发出事件的元素.
此外还存在相同功能的属性
它们是因兼容性而存在的属性, 不建议使用.
Event.srcElement 和 Event.toElement,它们是因兼容性而存在的属性, 不建议使用.
该方法用于停止事件传播, 即彻底切断之后的事件传播(与监听器所处的阶段无关, 之后的监听器全都收不到此事件).
但对于
为阻止此行为, 诞生了
但对于
currentTarget 上存在相同事件监听器的情况, 这些事件监听器仍能获取到此事件,为阻止此行为, 诞生了
stopImmediatePropagation().该方法不会阻止浏览器的默认行为, 例如点击链接仍将跳转到新的网页.
该方法用于停止事件传播, 与
该方法还会停止传播给在
stopPropagation() 的不同之处在于,该方法还会停止传播给在
currentTarget 上的其他事件监听器(即该元素的同一事件有多个监听器存在).该方法用于阻止浏览器的默认行为
(例如阻止勾选复选框, 阻止跳转到其他网页, 阻止在输入框里输入特定字符), 该方法不会停止事件的传播.
(例如阻止勾选复选框, 阻止跳转到其他网页, 阻止在输入框里输入特定字符), 该方法不会停止事件的传播.
如果一个事件的默认行为是不可取消的(
{ cancelable: false }), 则该方法没有效果.该行为被写在ResizeObserver的规范里, 但表现得像一个意外行为,
因为没有人会预期一个与尺寸变化相关的回调函数会立即执行.
因为没有人会预期一个与尺寸变化相关的回调函数会立即执行.
该行为的存在是可以理解的, 因为可能有用途需要记录观察对象相应属性的初始值.
在大多数情况下, 由于回调几乎是立即发生的, 该行为不会构成什么问题, 只是浪费一点CPU时间而已.
在大多数情况下, 由于回调几乎是立即发生的, 该行为不会构成什么问题, 只是浪费一点CPU时间而已.
然而, 存在一个与高频回调相关的最佳实践: debounce.
首次调用时触发回调和debounce的组合导致程序会产生一个略微滞后的回调行为, 很容易构成意外表现.
首次调用时触发回调和debounce的组合导致程序会产生一个略微滞后的回调行为, 很容易构成意外表现.
只有进入DOM的元素才有尺寸, 仅在JavaScript内存里存在的元素是无法获得尺寸的:
const element = document.createElement('div')element.style.width = '100%'element.style.height = '100%'element.offsetWidth // 0element.offsetHeight // 0element.getBoundingClientRect()// {// bottom: 0,// height: 0,// left: 0,// right: 0,// top: 0,// width: 0,// x: 0,// y: 0// }window.getComputedStyle(element).width // ''window.getComputedStyle(element).height // ''元素的布局属性, 这些属性不会反映元素的transform变换后的结果, 元素属性还会将值四舍五入为整数.
如果需要小数值和渲染属性(与布局属性相对), 则应该使用
如果需要小数值和渲染属性(与布局属性相对), 则应该使用
element.getBoudingClientRect().建议阅读: https://javascript.info/size-and-scroll
offsetWidth和offsetHeight是包括border和scroll在内的元素的可视尺寸值.
最接近 外观意义上的元素大小.
元素内容的大小, 不算border, 算上padding, 不算内容的scroll, 不算溢出可视范围的不可见部分.
元素内容的大小, 不算border, 算上padding, 算上溢出可视范围的不可见部分.
最接近 内容意义上的元素大小, 比如取整个文档的高度时, 就会使用scrollHeight.
元素左上角相对于offsetParent元素的padding构成的边界的偏移.
这些属性很少被使用.
层级上最近的具有位置的(positioned)祖先元素.
元素margin与padding之间的距离.
通常相当于元素左border的宽度和上border的高度.
通常相当于元素左border的宽度和上border的高度.
如果存在左/上滚动条, 则也会包括滚动条的宽度/高度.
元素当前滚动位置与完整内容的左/上边缘之间的距离.
属性是可写的, 用于调整滚动位置.
数值可以精确到子像素, 类型为浮点数.
鼠标指针在整个文档(页面)的坐标.
x, y是clientX, clientY的别名.
鼠标指针相对于视口左上角的坐标.
鼠标指针相对于元素左上角(考虑padding)的坐标.
该坐标反映tranform变化.
鼠标指针在整个屏幕的坐标.
在满足条件的多屏幕环境中, 将变成多个屏幕的组合值.
鼠标指针与前一个mousemove事件之间的像素坐标差异.
计算方式为当前screen坐标减去上一个screen坐标.
触控来源的宽度和高度, 例如手指按压区域的大小.
触控笔与屏幕的角度信息.
返回元素基于视口的各项渲染属性, 会反映transform变换后的结果.
比元素属性精度高, 值可以带有小数.
比元素属性精度高, 值可以带有小数.
此方法对元素边界的定义等同于元素属性的offsetWidth和offsetHeight.
该函数获取元素计算后的CSS属性, 通过它获取得到的width和height属性是应用值字符串, 即它们只会是
px 单位的字符串.即样式表里权重最高的属性值, 该值要么是用户设置, 要么是继承自父元素的, 要么是初始值.
计算值是根据规范计算出来的值, 它会将大多数特殊值和相对值转换为绝对值.
但是, 对于那些需要布局才能确定绝对值的属性, 它仍然无法得出绝对值.
但是, 对于那些需要布局才能确定绝对值的属性, 它仍然无法得出绝对值.
在CSS 2.0时, 计算值就是最终值, 在CSS 2.1中被新增的应用值取代.
应用值是渲染时最终使用的绝对值, 大部分应用值与计算值相同,
只有部分与布局有关的属性不同, 因为这些属性直到此时才确定下来.
只有部分与布局有关的属性不同, 因为这些属性直到此时才确定下来.
在CSS 2.1时, 引入了应用值的概念, 取代了CSS 2.0的计算值作为最终值.
contenteditable的缺点在于浏览器行为缺乏一致性, 生成的HTML结果大相径庭.
Monaco这样的编辑器会使用一个隐形的textarea处理用户输入,
实时将用户输入反应到渲染上.
实时将用户输入反应到渲染上.
async属性表示该脚本独立于页面和其他脚本, 它不受执行顺序的影响, 可以在任何时间点运行.
带有async属性的脚本会与页面解析并行下载, 并在可用时立即运行.
带有async属性的脚本会与页面解析并行下载, 并在可用时立即运行.
async可以让页面在解析时不被脚本执行阻塞住.
带有defer的脚本会在文档解析完毕之后, DOMContentLoaded事件触发之前运行.
多个带有defer的脚本会按照它们在HTML里的先后顺序依次执行.
多个带有defer的脚本会按照它们在HTML里的先后顺序依次执行.
defer可以让页面在解析时不被脚本执行阻塞住.
defer不对内联脚本生效, 内联脚本仍然会立即执行.
无论图片载入成功与否, 图片的complete属性都会被设置为true.
浏览器在img和iframe上原生具有一个名为loading的属性, 可以实现懒加载.
Safari是主流浏览器里唯一不支持此属性的.
https://caniuse.com/loading-lazy-attr
https://caniuse.com/loading-lazy-attr
https://github.com/aFarkas/lazysizes
user agent会在图片加载失败时显示破碎图片, 这有可能破坏页面的设计.
比如指定了尺寸的图片在载入失败后会于破碎图片上出现边框,
在Chrome(v92)上, 破碎图片的边框有时会无视元素所在容器的尺寸溢出.
比如指定了尺寸的图片在载入失败后会于破碎图片上出现边框,
在Chrome(v92)上, 破碎图片的边框有时会无视元素所在容器的尺寸溢出.
object元素的一个鲜为人知的功能是它在无法加载资源时会将它的后代作为fallback:
<object data="avatar.jpg" type="image/jpg"> <img src="default.jpg" /></object>该方案的缺陷是object元素不支持响应式图片切换.
参考: https://stackoverflow.com/a/29111371/5462167
如果指定了alt, 会显示替代图片的文本.
一些浏览器在显示替代文本后就不会显示破碎图片, 一些浏览器会将替代文本显示在破碎图片的右侧.
重点在于, 使用空alt时, 通常会引入特殊行为, 既不显示破碎图片, 也不显示替代文本.
一些浏览器在显示替代文本后就不会显示破碎图片, 一些浏览器会将替代文本显示在破碎图片的右侧.
重点在于, 使用空alt时, 通常会引入特殊行为, 既不显示破碎图片, 也不显示替代文本.
对picture元素来说, 此方案可能无效, 可能是因为相关行为没有被明确定义.
可以通过onError事件修改图片的src属性完成.
picture和source元素的组合是img元素srcset和sizes属性的替代品.
浏览器会按顺序从上到下选取最适合的图片资源, 因此条件最苛刻的项目应该排在最前面.
最后一个img元素将作为实际使用的img元素, 如果需要给图片设置alt属性, 则应该设置在此元素上.
最后一个img元素将作为实际使用的img元素, 如果需要给图片设置alt属性, 则应该设置在此元素上.
示例:
<picture> <source srcset="image.avif" type="image/avif" /> <source srcset="image.webp" type="image/webp" /> <img src="image.jpg" /></picture>picture和source元素都没有error事件, 在资源出错时仍然需要从img元素上捕获error事件.
picture元素内的source和img只用于为浏览器选取最合适的资源,
当资源无法访问时, 并不会由下一个项目替代无法访问的资源.
当资源无法访问时, 并不会由下一个项目替代无法访问的资源.
由于无法手动控制picture选择将哪个资源选为实际使用的资源,
因此当需要处理资源访问错误时, 也无法像直接使用img那样给src属性重新设置一个替代图像URL就解决问题,
而是要先找到导致失败的那个子元素, 然后修改子元素的属性.
因此当需要处理资源访问错误时, 也无法像直接使用img那样给src属性重新设置一个替代图像URL就解决问题,
而是要先找到导致失败的那个子元素, 然后修改子元素的属性.
当前使用的资源URL可以通过
因此未必与元素上设置的attribute值相同.
加上srcset可以包含查询条件, 通过currentSrc匹配出错的元素会很麻烦, 因此不建议使用此方案.
img.currentSrc 得到, 该属性是一个只读属性, 值是绝对URL,因此未必与元素上设置的attribute值相同.
加上srcset可以包含查询条件, 通过currentSrc匹配出错的元素会很麻烦, 因此不建议使用此方案.
这是推荐的解决方案, 在出错后移除img以外的所有source元素, 将img作为最终fallback使用.
使用此资源时需要满足的媒体查询条件.
示例:
(max-height: 500px)资源的URL.
与img元素的srcset属性类似, 是由逗号分隔的一组规则, 但一般只是被用来替代src的功能.
如果srcset属性里包含规则, 则浏览器会把规则视作一种媒体查询条件.
然而, 无论是宽度描述符还是像素密度描述符, 都可以被media属性的媒体查询替代, 没有必要在srcset里使用规则.
然而, 无论是宽度描述符还是像素密度描述符, 都可以被media属性的媒体查询替代, 没有必要在srcset里使用规则.
定义元素的mime类型.
该属性是由逗号分隔的一组规则, 定义浏览器可以选择的资源.
在没有sizes属性的情况下, 浏览器会自己根据显示设备选择相应的资源, 例如Retina屏幕会选择2x的资源.
在没有sizes属性的情况下, 浏览器会自己根据显示设备选择相应的资源, 例如Retina屏幕会选择2x的资源.
规则的语法:
<url> 省略描述符的资源, 该定义相当于 <url> 1x.<url> <width>w 带有宽度描述符的资源, width是一个正整数.<url> <pixel density>x 带有像素密度描述符的资源, pixel density是一个正浮点数.像素密度指的是1个CSS像素代表几个物理像素, 1x即为1:1, 2x即为1:2, 以此类推.
1个CSS像素固定为1英寸的96分之1, 代表96ppi的屏幕.
像素密度为2x时, 屏幕为192ppi.
像素密度为3x时, 屏幕为288ppi.
像素密度通常最高只用到4x, 平板电脑和显示器通常在1~2x之间, 超过2x的像素密度一般只出现在手机上.
由于手机是移动设备, 提供更高分辨率的图片意味着需要更多资源, 实际上没有提供高于2x图片的强烈需求.
1个CSS像素固定为1英寸的96分之1, 代表96ppi的屏幕.
像素密度为2x时, 屏幕为192ppi.
像素密度为3x时, 屏幕为288ppi.
像素密度通常最高只用到4x, 平板电脑和显示器通常在1~2x之间, 超过2x的像素密度一般只出现在手机上.
由于手机是移动设备, 提供更高分辨率的图片意味着需要更多资源, 实际上没有提供高于2x图片的强烈需求.
当像素密度并非是一个整数时.
可以通过
window.devicePixelRatio 得到浏览器当前的像素密度值.该属性是由逗号分隔的一组规则, 用于表示在特定viewport下最佳的资源宽度,
浏览器会从srcset属性里选择对应宽度的资源.
为了使用sizes属性, srcset的必须以
浏览器会从srcset属性里选择对应宽度的资源.
为了使用sizes属性, srcset的必须以
w 描述符来定义宽度, 否则该属性会失效.规则的语法:
最后一条规则可以作为缺省值, 此时允许省略media condition部分.
<media condition> <size>最后一条规则可以作为缺省值, 此时允许省略media condition部分.
示例:
(max-height: 500px) 1000px 如果viewport的高度低于500px, 则从srcset里挑选1000px的资源.如果该srcset属性不存在,或不包含具有宽度描述符的值,则该sizes属性无效。
受支持最广泛的有损压缩格式.
浏览器支持相当不错的格式.
webp同时支持有损压缩和无损压缩:
- 无损压缩的webp是png的直接替代品, 相同文件的体积比png小至少20%.
- 有损压缩的webp经常被营销为比jpeg的压缩比高, 但实际情况并非如此.
webp的quality参数有一定欺骗性, 容易使人错误地认为它与同等quality的jpeg具有相似质量但文件更小.
在高quality参数(80以上, 80通常是quality参数的默认值)的情况下, webp的效果要比同等quality的jpeg差.
由于webp会产生类似视频压缩的涂抹, 它的有损压缩很可能不适用于纹理细节丰富的图片.
因此, webp实际上需要比jpeg更高的quality参数, 而这也意味着两者的文件体积需要更接近(甚至webp文件会更大).
过慢的编码器在很大程度上抵消了采用webp的好处.
至少在sharp中, webp编码器比jpeg和png的编码器要慢得多.
至少在sharp中, webp编码器比jpeg和png的编码器要慢得多.
avif是一个受支持更少, 编码速度是离线级, 并且不支持渐进加载的图片格式.
看不到任何必要提供avif格式的图片的必要.
看不到任何必要提供avif格式的图片的必要.
当使用sharp(libvips)时, 发现avif的编码速度远逊于jpeg和webp.
在我的测试中, avif需要花费webp 20倍的时间才能达到webp的质量.
在我的测试中, avif需要花费webp 20倍的时间才能达到webp的质量.
:valid: 实时检测输入值的验证状态, 在通过验证的情况下应用样式.:user-valid: valid的用户交互版本, 只在用户交互后, 且通过验证的情况下应用样式.:invalid: 实时检测输入的验证状态, 在未通过验证的情况下应用样式.:user-invalid: invalid的用户交互版本, 只在用户交互后, 且未通过验证的情况下应用样式.
该元素经过本地化的, 供用户阅读的验证失败信息.
该元素的验证开关.
返回元素的ValidityState对象.
用于获取验证失败的具体原因.
验证元素, 通过验证时返回true, 反之返回false.
等同于checkValidity方法, 但在未通过验证的情况下会在用户界面弹出验证失败信息.
注意, 该方法在未通过验证的情况下并不会抛出异常, 因此后续代码仍会执行.
自定义元素的验证失败信息.
设置空字符串时, 元素被视为验证通过.
设置非空字符串时, 元素被视为验证未通过.
设置非空字符串时, 元素被视为验证未通过.
注意, 单纯设置失败信息并不会弹出失败信息, 需要手动调用reportValidity方法来弹出失败信息.
在移动设备上, 这些原生input元素可以提供比自定义组件更好的用户体验:
- date(专门的输入控件)
- time(专门的输入控件)
- datetime-local(专门的输入控件, Firefox有bug所以不支持)
- month(专门的输入控件)
- week(专门的输入控件)
- tel(专门的键盘)
- number(专门的键盘)
- password(会出现密码管理器的提示)
- color(专门的输入控件)
- innerText
获取基于布局的内容文本.
该属性忠于以文本在网页上的排版效果返回文本(因此性能较差). 其结果类似于选中文本后复制得到的文本.
由IE最先引入, 标准化较晚.
由于实现该属性需要引入布局支持, JSDOM未正确实现该属性.
当从上一级节点获取innerText时, 像`<script>`和`<style>`这样的子元素内的文本内容不会被包含.
- textContent
获取所有文本节点的串联文本, 这意味着空白符将与源代码一致.
该属性会忽略文本在网页上的显示效果, 忽略`<br>`, `<p>`等元素对排版的影响.
当从上一级节点获取textContent时, 像`<script>`和`<style>`这样的子元素内的文本内容也会被包含.
HTMLElement是Element的子类.
HTMLElement显式表示自己是HTML元素, Element则适用于所有类型的元素, 例如XML元素(最常见的例子是内嵌于HTML的svg).
一些属性只存在于HTML元素, 例如className, dataset.
鼠标双击的事件.
关于dblclick有一个臭名昭著的问题: 短时间内的连续点击(例如快速双击两次)只会触发一次双击事件.
这使得它变得相当不可靠, 开发者们宁可用click事件的
这使得它变得相当不可靠, 开发者们宁可用click事件的
e.detail 属性来处理此需求.与MouseEnter/MouseLeave相似, 区别在于:
- 事件会冒泡, 因此父元素会接收到子元素的MouseOver和MouseOut事件.
- 鼠标指针移动到子元素上时, 会触发MouseOut.
onMouseOver和onMouseOut事件有relatedTarget属性,
分别指代鼠标指针移进之前的元素和鼠标指针移除之后的元素.
分别指代鼠标指针移进之前的元素和鼠标指针移除之后的元素.
当鼠标从窗口外移入或移出窗口时, 该属性的值可能为null.
快速的鼠标移动有可能不触发MouseOver事件.
没有触发MouseOver, 就不会触发MouseOut.
没有触发MouseOver, 就不会触发MouseOut.
可以保证的是, 如果触发了MouseOver事件, 则一定会触发相应的MouseOut.
与MouseOver和MouseOut相似, 区别在于:
- 事件不会冒泡.
- 鼠标指针移动到子元素上时, 不会触发MouseLeave.
pointer系列事件是替代部分mouse和touch系列事件的新标准.
https://javascript.info/pointer-events
https://javascript.info/pointer-events
在PointerDown事件里调用后,
允许后续的PointerMove事件在指针/手指脱离目标元素的情况下继续触发,
出入界相关的事件(PointerOver/PointerOut, PointerEnter/PointerLeave等)将不触发,
直到出现PointerUp/PointerCancel事件为止.
允许后续的PointerMove事件在指针/手指脱离目标元素的情况下继续触发,
出入界相关的事件(PointerOver/PointerOut, PointerEnter/PointerLeave等)将不触发,
直到出现PointerUp/PointerCancel事件为止.
最常见的用途是制作可以拖动的元素, 例如滑块(slider).
在事件监听器里调用此方法setPointerCapture后, 后续指针事件都会在目标元素上触发.
然而, 不同浏览器存在严重的差异和错误:
https://github.com/w3c/pointerevents/issues/356
然而, 不同浏览器存在严重的差异和错误:
https://github.com/w3c/pointerevents/issues/356
- 在Chromium里, 如果在
e.currentTarget而不是e.target上捕获鼠标指针,
可能会导致目标元素的后代元素收不到一部分事件(似乎主要受影响的是PointerUp事件),
例如后代元素中的单选框将因此变得无法选中或取消(而其他类型的input则可能不受影响).
手动在对应的后代元素的PointerDown事件上阻止事件传播可以解决此问题, 但实施非常不方便. - https://github.com/GoogleChromeLabs/pointer-tracker/issues/4
- https://stackoverflow.com/a/79244099/5462167
- 在Firefox里, 目标元素后代元素的一些事件将会被错误地触发:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1885232
该事件已经被弃用, 主张用keydown事件替代它.
- 1.keypress事件接收到的已废弃属性
KeyboardEvent.keyCode和KeyboardEvent.which与keyup和keydown不同. - 2.keypress不会单独响应修饰键, 例如单独按下弹起
Ctrl不会触发事件.
img + p该组合器选择紧跟img元素的相同级别的p元素.
配合
:has() 伪类可选择img元素.img ~ p该组合器选择位于img元素之后的相同级别的p元素.
配合
:has() 伪类可选择img元素.在不选择平级/后代元素的情况下, 添加平级/后代元素的匹配条件.
这是一个需求相当大, 但实现得相当晚的伪类, 直到2023年才广泛可用.
由于匹配成本较高, 可能会对性能造成影响.
由于匹配成本较高, 可能会对性能造成影响.
参数为
, 分隔的选择器列表.div:has(a, b) 等价于 div:has(a), div:has(b), 不同于 div:has(a):has(b).img:has(+ p) /* 选择img元素, 该img元素后面需要紧跟一个p元素 */img:has(~ p) /* 选择img元素, 该img元素之后需要有一个p元素 */div:has(span) /* 选择div元素, 该div元素包含一个span后代元素 */div:has(> span) /* 选择div元素, 该div元素包含一个span子元素 */用于排除不需要的元素.
参数为
, 分隔的选择器列表.:not(.foo, .bar) 等价于 :not(.foo):not(.bar).当参数包含无效的选择器时, 整条规则都会无效.
可配合
可配合
:is() 伪类使用来提升其鲁棒性.用于简化CSS编写和提升选择器的健壮性.
曾被命名为
曾被命名为
:matches(), 这是一个更准确的命名, 但已经被WebKit使用了.参数为
, 分隔的选择器列表.:is(div, span) :is(div, span)/* 等价于 */div div,div span,span div,span span:is() 参数在包含无效选择器时, 不会将整条规则视作无效.:is()的特异性为选择器列表中最具体选择器的特异性.:where()的特异性始终为0.
p:nth-of-type(4n)该伪类选中同级别序数为4的倍数的p元素.
其他形式:
p:nth-of-type(1)p:nth-of-type(4n+1)p:nth-of-type(even)p:nth-of-type(odd):nth-of-type 出现的原因是为了弥补 :nth-child 在功能上的不足::nth-child是按所有同级元素的绝对索引值选择元素的,
在选择元素后才会检查元素是否与其他选择器相匹配.:nth-of-type是先基于元素类型获取元素列表, 然后才开始按顺序匹配,
需要的元素类型以外的元素不会被被列入这个列表里, 因此每一项索引值都对应一个此类型的元素.
该伪类选择没有任何兄弟元素的元素.
p:only-of-type该伪类选择同级别, 没有其他相同类型元素的元素.
该伪类选择同级别, 此类型元素中的第一个元素.
该伪类选择同级别, 此类型元素中的最后一个元素.
该伪类的作用是选择URL hash对应id的元素.
因此, 当URL为
该伪类指代
https://example.com/index.html#section1 时,该伪类指代
<section id="section1">Example</section>此伪类选择没有子元素的元素.
伪元素使用两个冒号
旧的伪元素规范使用单个冒号
::, 例如 ::before 和 ::after.旧的伪元素规范使用单个冒号
:, 为保持兼容性, 大多数浏览器仍支持旧伪元素的单冒号语法.::before::afterli::marker::selectiona[title] /* 存在此属性 */a[title="title"] /* 属性值等于 */a[title="title" i] /* 属性值等于(忽略大小写) */a[title*="title"] /* 属性值包含 */a[title^="title"] /* 属性值头部等于 */a[title$="title"] /* 属性值尾部等于 */a[title~="title"] /* 属性值是以单词的形式包含(像class那样) *//li 根节点(文档)下的li子节点//li 根节点(文档)所有的后代li节点./ 可省略, 因此 li 等同于 ./li.//title[@lang='eng']//li[@class="item"] 此匹配只对class属性完全等于item的元素有效//li[contains(@class, "item")] 此匹配对任何包含item的class属性有效//li[contains(@class, "item") and @name="item"] 匹配多个属性//li[starts-with(@class, "item")] 匹配以特定字符串开头的属性//li/a/@href/text() 返回文本节点//h2[text()="Title"] 返回文本满足条件的元素元素序号从1开始.
//li[1]/a/text//li[last()]/a/text//li[position()<3]/a/text() 前两个//li[last()-2]/a/text() 倒数第三个//li[1]/ancestor::* 返回所有祖先//li[1]/ancestor::div 返回所有div祖先//li[1]/attribute::* 返回所有属性值//li[1]/child::a[@href="link.html"] 所有符合href属性条件的a子节点//li[1]/descendant::span 所有span后代节点//li[1]/following::*[2] 当前节点之后(同文档下)的第二个节点//li[1]/following-sibling::* 当前节点之后的所有同级(兄弟)节点| 运算符 | 描述 | 例子 |
|---|---|---|
or | 或 | |
and | 与 | |
mod | 取余 | |
| 管道符号 | 计算节点集 | //book 管道符号 //cd |
+ | 加法 | |
- | 减法 | |
* | 乘法 | |
div | 除法 | |
= | 等于 | |
!= | 不等于 | |
< | 小于 | |
<= | 小于或等于 | |
> | 大于 | |
>= | 大于或等于 |
HTML5虽然通过带有语义的标签提升了网页的可访问性, 但实际上网页的可访问性仍是一团糟.
可访问性问题的根源来自于以下几点:
- 一些HTML标签对嵌套的后代标签有限制, 导致越来越多的项目选择直接将div和span作为解决方案.
- 网页提供的用户界面(元素)是碎片化的, 自制组件在网页开发过程中很普遍.
- 即使网页像Windows程序那样有着标准的系统控件, 最终也会因为不满足实际需求而被自定义控件替代.
- 可访问性工具市场未能达成统一意见, 也没有跟上最新的推荐标准.
- 开发人员在考虑功能实现的同时还需要考虑可访问性, 形成了认知负担.
- 在相当多的国家缺乏保证可访问性的法律法规, 而大部分业务并不考虑残障人士市场, 因此缺乏驱动力.
由于可访问性的优先级总是会低于实际需求, 即使开发人员非常专注于提升网页的可访问性, 也经常会被新的变化破坏.
虽然像MDN这样的网站会告诉你可访问性不是"全有或是全无",
但在缺乏专职人员的情况下, 检验可访问性很可能要求开发人员遍历W3C规范和全部的HTML, 因此会成为一项繁重的任务.
如果机器能够自动检查语义, 那么就不需要开发人员添加标签了, 因此难以指望通过工具减少负担.
但在缺乏专职人员的情况下, 检验可访问性很可能要求开发人员遍历W3C规范和全部的HTML, 因此会成为一项繁重的任务.
如果机器能够自动检查语义, 那么就不需要开发人员添加标签了, 因此难以指望通过工具减少负担.
浏览器等user agent使用的一种内部的结构化表示.
可访问性树是DOM树的替代版本, 从DOM树中摘取自己能够/愿意识别的元素构建而来.
可访问性树是DOM树的替代版本, 从DOM树中摘取自己能够/愿意识别的元素构建而来.
可访问性树未来可能会被可访问性对象模型(AOM, Accessibility Object Model)取代.
W3C的一种规范, 用于改善可访问性.
W3C提供的ARIA使用指导: https://w3c.github.io/using-aria/
理论上, 在HTML5里已经存在的语义元素不应该被设置aria属性.
驱动人们使用WAI-ARIA的原因可能是因为一些组件测试库强制要求使用aria属性作为选择器.
W3C提供的role列表: https://www.w3.org/TR/wai-aria-1.1/#role_definitions
MDN提供的role文档: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#roles
MDN提供的role文档: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#roles
语义化元素承担的角色, 使用
(现代网页的类名经常是随机值).
role 属性设置, 在一些网站上已经彻底取代传统的css类名(现代网页的类名经常是随机值).
aria先于HTML5出现, 并且部分成为HTML5的元素.
由于其多样性, 不难发现可以在很大程度上取代HTML5的语义元素,
但 规范要求开发人员优先使用现有的语义HTML元素, 而不是提供aria.
如果与现成元素出现语义上的冲突, 则 不得改变现有语义HTML元素, 而是建议用div替代.
由于其多样性, 不难发现可以在很大程度上取代HTML5的语义元素,
但 规范要求开发人员优先使用现有的语义HTML元素, 而不是提供aria.
如果与现成元素出现语义上的冲突, 则 不得改变现有语义HTML元素, 而是建议用div替代.
表明这是段落.
该角色尚未得到工具链的广泛支持.
表明这是导航条.
表明这是搜索表单.
表明这是文章单元, 可能在页面中有多个这样的单元.
表明这是补充内容.
表明这是警告.
表明这是进度条.
语义化元素的属性.
个人不推荐深入相关属性, 因为这些属性的理想化成分过多, 对于实际使用这些可访问性标签的工具来说可能根本没有意义.
个人不推荐深入相关属性, 因为这些属性的理想化成分过多, 对于实际使用这些可访问性标签的工具来说可能根本没有意义.
该元素的最小值.
该元素的最大值.
表示这是一项动态更新的内容(通常由JavaScript导致), 有几种不同的值.
默认值, 内容更新不应该告知用户.
当用户空闲时, 告知用户内容更新.
应该尽快告知用户内容更新.
通常与aria-iive一同使用.
aria-atomic="true" 表示元素是一个原子, 屏幕阅读器应该读出整个元素, 而不仅仅是更新的内容.功能上类似于aria-atomic.
表示此项必填.
aria-required="true"表示此项被禁用.
aria-disabled="true"语义化元素的当前状态.
提升键盘可访问性, 用于改变元素的焦点顺序.
tabindex="0" 让通常不可变为焦点的元素支持变为焦点.