一个 页面元素选中高亮 Hook
# 图例

# 使用
在开发环境下,按住 command 后,鼠标移入到页面上的 dom 元素,可以被点击的 dom 元素会出现蓝色边框
点击 dom 元素之后触发 click 事件,将 dom 上的属性
data-sf``data-sl
加入到参数中,然后去请求接口vscode/openfile
后续操作由接口
vscode/openfile
执行接口
vscode/openfile
会根据传入的data-sf``data-sl
,精准打开 vscode,并跳转到与之对应的源码位置很大程度上方便了开发者在开发环境下的调试;提供了再多人协作的项目中,改 bug 时、改其他人代码时候,快速定位代码的功能
# 实现代码
点击 展开/收起 jsx 代码
/**
* @des 结合插件跳转到 vscode,在页面上元素高亮
*/
import { useState, useEffect } from 'react';
export const useHighlightOnCommand = () => {
const [isCommandPressed, setIsCommandPressed] = useState(false);
const [highlightedElement, setHighlightedElement] = useState(null);
useEffect(() => {
const handleClick = (event) => {
if (event.metaKey) {
event.preventDefault();
event.stopPropagation();
const { target } = event;
const filePath = target.getAttribute('data-sf');
const lineNumber = target.getAttribute('data-sl');
const columnNumber = 0;
const url = new URL('/vscode/openfile', window.location.origin);
url.searchParams.append('filePath', filePath);
url.searchParams.append('lineNumber', lineNumber);
url.searchParams.append('columnNumber', columnNumber);
console.log('filePath', filePath, lineNumber);
if (filePath && lineNumber) {
fetch(url.href, {
method: 'GET',
}).catch((err) => console.error('跳转vscode:', err));
} else {
console.error('dom的babel信息错误');
}
}
};
const handleKeyDown = (event) => {
if (event.metaKey) {
setIsCommandPressed(true);
}
};
const handleKeyUp = (event) => {
if (!event.metaKey) {
setIsCommandPressed(false);
if (highlightedElement) {
highlightedElement.classList.remove('can-open-vscode');
setHighlightedElement(null);
}
}
};
const handleMouseMove = (event) => {
if (isCommandPressed) {
let targetElement = event.target;
// 向上查找,直到找到具有 data-sf 属性的元素或到达根元素
while (targetElement && !targetElement.getAttribute('data-sf')) {
targetElement = targetElement.parentElement;
}
if (targetElement) {
if (highlightedElement && highlightedElement !== targetElement) {
highlightedElement.classList.remove('can-open-vscode');
}
if (!highlightedElement || highlightedElement !== targetElement) {
targetElement.classList.add('can-open-vscode');
setHighlightedElement(targetElement);
}
} else {
if (highlightedElement) {
highlightedElement.classList.remove('can-open-vscode');
setHighlightedElement(null);
}
}
}
};
if (process.env.NODE_ENV === 'development') {
window.addEventListener('click', handleClick, true);
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
document.addEventListener('mousemove', handleMouseMove);
}
return () => {
window.removeEventListener('click', handleClick, true);
document.removeEventListener('keydown', handleKeyDown);
document.removeEventListener('keyup', handleKeyUp);
document.removeEventListener('mousemove', handleMouseMove);
};
}, [isCommandPressed, highlightedElement]);
return null; // 这个 Hook 不需要返回任何内容
};