optimize xpath
This commit is contained in:
1 parent
6f81dba0b6
commit
bc19b204e1
5 files changed
+235
-34
No files matched your search
+113
-34
@@ -59,37 +59,88 @@
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建启用复制模式消息提示
|
||||||
|
function createCopyModeMessage() {
|
||||||
|
const message = document.createElement('div');
|
||||||
|
message.innerHTML = '复制模式已启用';
|
||||||
|
message.style.position = 'fixed';
|
||||||
|
message.style.top = '10px';
|
||||||
|
message.style.left = '50%';
|
||||||
|
message.style.transform = 'translateX(-50%)';
|
||||||
|
message.style.background = '#1E3A8A';
|
||||||
|
message.style.color = '#F9FAFB';
|
||||||
|
message.style.padding = '10px';
|
||||||
|
message.style.borderRadius = '5px';
|
||||||
|
message.style.display = 'none';
|
||||||
|
message.style.zIndex = '1001';
|
||||||
|
message.style.fontSize = '16px';
|
||||||
|
document.body.appendChild(message);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取元素的 XPath
|
// 获取元素的 XPath
|
||||||
function getElementXPath(element) {
|
function getElementXPath(element) {
|
||||||
if (element.id) {
|
if (!element) {
|
||||||
return `//*[@id="${element.id}"]`;
|
return '';
|
||||||
}
|
}
|
||||||
|
if (!element.parentNode) {
|
||||||
const parts = [];
|
return '/' + (element.tagName ? element.tagName.toLowerCase() : '');
|
||||||
while (element && element.nodeType === Node.ELEMENT_NODE) {
|
}
|
||||||
let selector = element.nodeName.toLowerCase();
|
let ix = 0;
|
||||||
if (element.className) {
|
const siblings = element.parentNode.childNodes;
|
||||||
selector += `[@class="${element.className}"]`;
|
for (let i = 0; i < siblings.length; i++) {
|
||||||
} else if (element.textContent.trim()) {
|
const sibling = siblings[i];
|
||||||
selector += `[text()="${element.textContent.trim()}"]`;
|
if (sibling === element) {
|
||||||
} else if (element.id) {
|
return getElementXPath(element.parentNode) + '/' + (element.tagName ? element.tagName.toLowerCase() : '') + '[' + (ix + 1) + ']';
|
||||||
selector += `[@id="${element.id}"]`;
|
}
|
||||||
} else {
|
if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {
|
||||||
let sibling = element;
|
ix++;
|
||||||
let index = 1;
|
|
||||||
while (sibling.previousElementSibling) {
|
|
||||||
sibling = sibling.previousElementSibling;
|
|
||||||
if (sibling.nodeName.toLowerCase() === selector) {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
selector += `[${index}]`;
|
|
||||||
}
|
}
|
||||||
parts.unshift(selector);
|
|
||||||
element = element.parentNode;
|
|
||||||
}
|
}
|
||||||
// return parts.length ? '/' + parts.join('/') : null;
|
}
|
||||||
return "/xpath";
|
|
||||||
|
// Function to check if the current node is inside an iframe
|
||||||
|
function isInsideIframe() {
|
||||||
|
try {
|
||||||
|
return window.self !== window.top;
|
||||||
|
} catch (e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to get the index of the iframe containing the current node
|
||||||
|
function getIframeIndex() {
|
||||||
|
if (!isInsideIframe()) return -1;
|
||||||
|
const iframes = window.top.document.querySelectorAll('iframe');
|
||||||
|
for (let i = 0; i < iframes.length; i++) {
|
||||||
|
try {
|
||||||
|
if (iframes[i].contentWindow === window.self) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to get the XPath of an iframe
|
||||||
|
function getIframeXPath(iframe) {
|
||||||
|
if (!iframe) return '';
|
||||||
|
let xpath = '';
|
||||||
|
while (iframe && iframe !== document) {
|
||||||
|
let index = 0;
|
||||||
|
let sibling = iframe.previousSibling;
|
||||||
|
while (sibling) {
|
||||||
|
if (sibling.nodeType === 1 && sibling.tagName === iframe.tagName) {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
sibling = sibling.previousSibling;
|
||||||
|
}
|
||||||
|
xpath = '/' + iframe.tagName.toLowerCase() + '[' + (index + 1) + ']' + xpath;
|
||||||
|
iframe = iframe.parentNode ? iframe.parentNode : null;
|
||||||
|
}
|
||||||
|
return xpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听鼠标移动事件
|
// 监听鼠标移动事件
|
||||||
@@ -130,6 +181,21 @@
|
|||||||
const xpath = getElementXPath(element);
|
const xpath = getElementXPath(element);
|
||||||
console.log('Element XPath:', xpath);
|
console.log('Element XPath:', xpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the current node is inside an iframe and get its index
|
||||||
|
if (isInsideIframe()) {
|
||||||
|
const iframeIndex = getIframeIndex();
|
||||||
|
console.log('Current node is inside an iframe with index:', iframeIndex);
|
||||||
|
const iframes = window.top.document.querySelectorAll('iframe');
|
||||||
|
if (iframeIndex !== -1) {
|
||||||
|
const iframeXPath = getElementXPath(iframes[iframeIndex]);
|
||||||
|
|
||||||
|
console.log('Iframe XPath:', iframeXPath);
|
||||||
|
} else {
|
||||||
|
console.log('Iframe not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("=".repeat(50));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Function to remove highlight effect
|
// Function to remove highlight effect
|
||||||
@@ -148,11 +214,11 @@
|
|||||||
function addIframeMouseListeners() {
|
function addIframeMouseListeners() {
|
||||||
const iframes = document.querySelectorAll('iframe');
|
const iframes = document.querySelectorAll('iframe');
|
||||||
iframes.forEach(iframe => {
|
iframes.forEach(iframe => {
|
||||||
iframe.addEventListener('mouseenter', function() {
|
iframe.addEventListener('mouseenter', function () {
|
||||||
console.log('Mouse entered iframe:', iframe.src);
|
console.log('Mouse entered iframe:', iframe.src);
|
||||||
removeHighlightEffect();
|
removeHighlightEffect();
|
||||||
}, true);
|
}, true);
|
||||||
iframe.addEventListener('mouseleave', function() {
|
iframe.addEventListener('mouseleave', function () {
|
||||||
console.log('Mouse left iframe:', iframe.src);
|
console.log('Mouse left iframe:', iframe.src);
|
||||||
removeHighlightEffect();
|
removeHighlightEffect();
|
||||||
}, true);
|
}, true);
|
||||||
@@ -173,13 +239,21 @@
|
|||||||
function enableCopyModeInAllFrames() {
|
function enableCopyModeInAllFrames() {
|
||||||
isCopyModeEnabled = true;
|
isCopyModeEnabled = true;
|
||||||
console.log('Copy mode enabled in main window');
|
console.log('Copy mode enabled in main window');
|
||||||
|
copyModeMessage.style.display = 'block';
|
||||||
|
setTimeout(() => {
|
||||||
|
copyModeMessage.style.display = 'none';
|
||||||
|
}, 3000);
|
||||||
const iframes = document.querySelectorAll('iframe');
|
const iframes = document.querySelectorAll('iframe');
|
||||||
iframes.forEach(iframe => {
|
iframes.forEach(iframe => {
|
||||||
iframe.contentWindow.postMessage({ action: 'enableCopyMode' }, '*');
|
try {
|
||||||
iframe.contentWindow.addEventListener('mouseleave', function() {
|
iframe.contentWindow.postMessage({ action: 'enableCopyMode' }, '*');
|
||||||
console.log('Mouse left iframe:', iframe.src);
|
iframe.contentWindow.addEventListener('mouseleave', function () {
|
||||||
removeHighlightEffect();
|
console.log('Mouse left iframe:', iframe.src);
|
||||||
});
|
removeHighlightEffect();
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error accessing iframe:', error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +264,11 @@
|
|||||||
console.log('Copy mode disabled in main window');
|
console.log('Copy mode disabled in main window');
|
||||||
const iframes = document.querySelectorAll('iframe');
|
const iframes = document.querySelectorAll('iframe');
|
||||||
iframes.forEach(iframe => {
|
iframes.forEach(iframe => {
|
||||||
iframe.contentWindow.postMessage({ action: 'disableCopyMode' }, '*');
|
try {
|
||||||
|
iframe.contentWindow.postMessage({ action: 'disableCopyMode' }, '*');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error accessing iframe:', error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,4 +334,5 @@
|
|||||||
|
|
||||||
copyButton = createCopyButton();
|
copyButton = createCopyButton();
|
||||||
copyMessage = createCopyMessage();
|
copyMessage = createCopyMessage();
|
||||||
|
const copyModeMessage = createCopyModeMessage();
|
||||||
})();
|
})();
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
function getElementXPath(element) {
|
||||||
|
if (element.id) {
|
||||||
|
return `//*[@id="${element.id}"]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断元素是否在iframe中
|
||||||
|
let currentElement = element;
|
||||||
|
let iframe = null;
|
||||||
|
while (currentElement) {
|
||||||
|
if (currentElement.tagName && currentElement.tagName.toLowerCase() === 'iframe') {
|
||||||
|
iframe = currentElement;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentElement = currentElement.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe) {
|
||||||
|
const iframeXPath = getElementXPath(iframe);
|
||||||
|
const elementXPath = getElementXPath(element);
|
||||||
|
return iframeXPath + elementXPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts = [];
|
||||||
|
while (element && element.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
let selector = element.nodeName.toLowerCase();
|
||||||
|
if (element.className) {
|
||||||
|
selector += `[@class="${element.className}"]`;
|
||||||
|
} else if (element.textContent.trim()) {
|
||||||
|
selector += `[text()="${element.textContent.trim()}"]`;
|
||||||
|
} else if (element.id) {
|
||||||
|
selector += `[@id="${element.id}"]`;
|
||||||
|
} else {
|
||||||
|
let sibling = element;
|
||||||
|
let index = 1;
|
||||||
|
while (sibling.previousElementSibling) {
|
||||||
|
sibling = sibling.previousElementSibling;
|
||||||
|
if (sibling.nodeName.toLowerCase() === selector) {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selector += `[${index}]`;
|
||||||
|
}
|
||||||
|
parts.unshift(selector);
|
||||||
|
element = element.parentNode;
|
||||||
|
}
|
||||||
|
return parts.length ? '/' + parts.join('/') : null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: lightblue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<input id="username"/>
|
||||||
|
<button id="submit">Submit</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<iframe id="iframe" src="local-page2.html" width="100%" height="200px" frameborder="0"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: lightgreen;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<input id="username"/>
|
||||||
|
<button id="submit">Submit</button>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input type="text" id="urlInput" placeholder="Enter URL">
|
||||||
|
<button onclick="loadIframe()">Submit</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<iframe id="iframe" src="local-page.html" width="100%" height="200px" frameborder="0"></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<iframe id="iframe" src="local-page.html" width="100%" height="200px" frameborder="0"></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function loadIframe() {
|
||||||
|
var url = document.getElementById('urlInput').value;
|
||||||
|
document.getElementById('iframe').src = url;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in new issue
Block a user