假设我有一个带有不同种类标记的大型HTML文件,类似于您现在正在查看的StackOverflow。
现在,假设您单击页面上的一个元素,那么该Javascript函数将如何计算出引用该特定元素的最基本的XPath?
我知道在XPath中有无数种方式来引用该元素,但是我正在寻找一种只看DOM树而不考虑ID,类等的东西。
例:
<html> <head><title>Fruit</title></head> <body> <ol> <li>Bananas</li> <li>Apples</li> <li>Strawberries</li> </ol> </body> </html>
假设您点击“ 苹果” 。Javascript函数将返回以下内容:
/html/body/ol/li[2]
从根本上说,它只是将DOM树一直向上扩展到HTML元素。
只是为了澄清,“单击”事件处理程序不是问题。我可以做的。我只是不确定如何计算元素在DOM树中的位置并将其表示为XPath。
PS任何使用或不使用JQuery库的答案,我们都应感谢。
PPS我对XPath完全陌生,因此在上面的示例中我甚至可能犯了一个错误,但是您会明白的。
Firebug可以做到这一点,它是开源BSD的,因此您可以重复使用它们的实现,而无需任何库。
这是上面链接源的摘录。以防万一上面的链接会改变。请检查源以从更改和更新或提供的完整功能集中受益。
Xpath.getElementXPath = function(element) { if (element && element.id) return '//*[@id="' + element.id + '"]'; else return Xpath.getElementTreeXPath(element); };
上面的代码调用此函数。注意,我添加了一些换行符以避免水平滚动条
Xpath.getElementTreeXPath = function(element) { var paths = []; // Use nodeName (instead of localName) // so namespace prefix is included (if any). for (; element && element.nodeType == Node.ELEMENT_NODE; element = element.parentNode) { var index = 0; var hasFollowingSiblings = false; for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) { // Ignore document type declaration. if (sibling.nodeType == Node.DOCUMENT_TYPE_NODE) continue; if (sibling.nodeName == element.nodeName) ++index; } for (var sibling = element.nextSibling; sibling && !hasFollowingSiblings; sibling = sibling.nextSibling) { if (sibling.nodeName == element.nodeName) hasFollowingSiblings = true; } var tagName = (element.prefix ? element.prefix + ":" : "") + element.localName; var pathIndex = (index || hasFollowingSiblings ? "[" + (index + 1) + "]" : ""); paths.splice(0, 0, tagName + pathIndex); } return paths.length ? "/" + paths.join("/") : null; };