前言
今天面试官问了个有意思的问题,JS环境如何筛选出页面上的所有可交互元素?还不能用getEventListeners。
可交互元素:Twitter、Facebook上用户可以点击、输入或div、span等元素有事件监听器时(如点击、悬停),等其他方式与这些元素交互,都可称为可交互元素。
function getInteractiveElements(element: HTMLElement): HTMLElement[] {
// 1.禁止使用getEventListeners,因为只有devtool环境下才有权限
}
1.getEventListeners
好嘛,先来看看getEventListeners。
// 获取页面上所有元素
const allElements = document.querySelectorAll('*');
// 用于存储具有事件监听器的元素
const elementsWithListeners = [];
// 遍历所有元素
allElements.forEach(element => {
// 获取元素上的所有事件监听器
const listeners = getEventListeners(element);
// 检查是否有事件监听器
if (Object.keys(listeners).length > 0) {
elementsWithListeners.push(element);
}
});
2.判断属性的key和value
如果不用getEventListeners呢?也许可以通过属性key和value的类型来判断。
function hasEventListeners(element) {
for (const prop in element) {
//on开头的属性,属性内容为函数
if (prop.startsWith("on") && typeof element[prop] === "function") {
return true;
}
}
return false;
}
const allElements = document.querySelectorAll('*');
const elementsWithListeners = [];
allElements.forEach(element => {
if (hasEventListeners(element)) {
elementsWithListeners.push(element);
}
});
后续
但是面试官又开口了,on依然是从事件的角度入手去判断元素是否可交互,能不能不从事件的角度去判断呢?
疑惑:不从事件的角度?那普通的div和加了onclick的div有嘛区别嘛
面试官:aria-label
好嘛,直接改html去了。