zoukankan      html  css  js  c++  java
  • 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}`)
    })
    
  • 相关阅读:
    【洛谷4548】[CTSC2006] 歌唱王国(概率生成函数)
    概率生成函数初探
    【AT4432】[ARC103B] Robot Arms(构造)
    【AT4163】[ARC099D] Eating Symbols Hard(哈希)
    【洛谷5398】[Ynoi2018] GOSICK(莫队二次离线)
    【AT4353】[ARC101D] Robots and Exits(树状数组优化DP)
    【AT5161】[AGC037D] Sorting a Grid(二分图匹配)
    【CF573E】Bear and Bowling(分块维护凸壳)
    【CF611G】New Year and Cake(计算几何)
    【洛谷6791】[SNOI2020] 取石子(斐波那契博弈+数位DP)
  • 原文地址:https://www.cnblogs.com/yloved/p/13964756.html
Copyright © 2011-2022 走看看