js生成xpath


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}`)
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM