js生成xpath
yls 2020/11/12
class XpathGenerater {
fullPath = true
/**
* 生成給定節點對應的全路徑xpath
* @param {節點} el
*/
generateFullXPath(el) {
return this.generateXPath(el)
}
generateXPath(el) {
let query = ""
while (el && el.nodeType === Node.ELEMENT_NODE) {
// 也可以使用nodeName,nodeName包含了tagName
let component = el.tagName.toLowerCase()
let index = this.getElementIndex(el)
// 如果獲取相對路徑,並且id存在
if (!this.fullPath && el.id) {
component += `[@id='${el.id}']`
}
if (index >= 1) {
component += `[${index}]`
}
query = '/' + component + query
// 獲取相對路徑,嘗試執行 xpath 是否為唯一值
if (!this.fullPath) {
let temporaryQuery = `/${query}`
let test = document.evaluate(temporaryQuery, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
if (test.snapshotLength == 1) {
return temporaryQuery
}
}
el = el.parentNode
}
return query
}
/**
* 生成給定節點對應的相對路徑xpath
* @param {} el
*/
generateRelativeXPath(el) {
this.fullPath = false
return this.generateXPath(el)
}
/**
* 獲取當前元素節點在上一級節點中的位置
* 若沒有相同類型的兄弟節點,返回 0
*/
getElementIndex(el) {
let index = 1
let sib = el.previousSibling
while (sib) {
if (sib.nodeType === Node.ELEMENT_NODE && this.compareTagNameEqual(el, sib)) {
index++
}
sib = sib.previousSibling
}
if (index > 1) return index
sib = el.nextSibling
while (sib) {
if (sib.nodeType === Node.ELEMENT_NODE && this.compareTagNameEqual(el, sib)) {
return 1
}
sib = sib.nextSibling
}
return 0;
};
/**
* 查看兩個元素節點名稱是否相同
*/
compareTagNameEqual(primaryEl, siblingEl) {
let p = primaryEl, s = siblingEl
if (this.fullPath) {
// 獲取全路徑時,只比較tagName就足夠了
return (p.tagName === s.tagName)
} else {
// 當tagName相同時,則也比較id
return (p.tagName === s.tagName && (!(p.id) || p.id === s.id))
}
};
}
使用舉例
點擊頁面某一處,生成該處對應的xpath
document.addEventListener("click", function (event) {
//todo 點擊頁面時,可以通過加樣式改變顏色,也可以加遮罩層
//event.target.style.background = "rgba(213, 0, 0, 0.2)"
//event.target.style.outline = "rgb(199, 0, 0) solid 2px"
// 絕對路徑
let xpath = new XpathGenerater().generateFullXPath(event.target)
// 相對路徑
let relativeXPath = new XpathGenerater().generateRelativeXPath(event.target)
console.log(`xpath==========${xpath}`)
console.log(`relativeXPath==========${relativeXPath}`)
})