FOCUSABLE_ELEMENT_SELECTORS
const FOCUSABLE_ELEMENT_SELECTORS = `a[href],button:not([disabled]),button:not([hidden]),:not([tabindex="-1"]),input:not([disabled]),input:not([type="hidden"]),select:not([disabled]),textarea:not([disabled])`
isVisible
export const isVisible = (element: HTMLElement) => {
if (process.env.NODE_ENV === 'test') return true
const computed = getComputedStyle(element)
// element.offsetParent won't work on fix positioned
// WARNING: potential issue here, going to need some expert advices on this issue
return computed.position === 'fixed' ? false : element.offsetParent !== null
}
/*
getComputedStyle 获取到dom结构的样式对象集合
offsetParent
元素自身有fixed定位,父元素不存在定位,则offsetParent的结果未null
元素自身无fixed定位,且父元素不存在定位,offsetParent为 body元素
元素自身无fixed定位,且父元素存在定位,offsetParent为离自身最近且经过定位的父元素
body 元素的offsetParent是null
*/
解析
getComputedStyle 获取指定dom元素的样式属性结合
返回的是一个对象 通过属性名称即可访问
如 getComputedStyle(document.getElementById("dom"))['width] 即可访问到dom元素的宽度
offsetParent 距离当前元素最近的进行过定位的父元素
素自身有fixed定位,父元素不存在定位,则offsetParent的结果未null
元素自身无fixed定位,且父元素不存在定位,offsetParent为 body元素
元素自身无fixed定位,且父元素存在定位,offsetParent为离自身最近且经过定位的父元素
body 元素的offsetParent是null
obtainAllFocusableElements
export const obtainAllFocusableElements = (
element: HTMLElement
): HTMLElement[] => {
return Array.from(
element.querySelectorAll<HTMLElement>(FOCUSABLE_ELEMENT_SELECTORS)
).filter((item: HTMLElement) => isFocusable(item) && isVisible(item))
}
/*
obtainAllFocusableElements
入参
HTMLElement 单个dom元素
返回值
HTMLElement [] dom元素集合的 数组
Array.from 将伪数组转换为真实的数组
element.querySelectorAll 查找当前元素下的所有 满足条件的子元素 FOCUSABLE_ELEMENT_SELECTORS(子元素类名集合)
filter 过滤
isFocusable 和 isVisible 调用处理都返回true的
*/
obtainAllFocusableElements
入参
HTMLElement 单个dom元素
返回值
HTMLElement [] dom元素集合的 数组
Array.from 将伪数组转换为真实的数组
element.querySelectorAll 查找当前元素下的所有 满足条件的子元素 FOCUSABLE_ELEMENT_SELECTOR