Javascript 获取所单击对象的DOM路径<;a>;
HTML 警告信息如下: body div.lol a.rightArrow 如何使用javascript/jquery实现这一点?使用jquery,如下所示(接下来是一个除事件外不使用jquery的解决方案;如果这很重要,则函数调用要少得多): 现场示例:Javascript 获取所单击对象的DOM路径<;a>;,javascript,jquery,html,dom,css-selectors,Javascript,Jquery,Html,Dom,Css Selectors,HTML 警告信息如下: body div.lol a.rightArrow 如何使用javascript/jquery实现这一点?使用jquery,如下所示(接下来是一个除事件外不使用jquery的解决方案;如果这很重要,则函数调用要少得多): 现场示例: $(“.rightArrow”)。单击(函数(){ var rightArrowParents=[]; $(this).parents().addBack().not('html')。each(function()){ var entry
$(“.rightArrow”)。单击(函数(){
var rightArrowParents=[];
$(this).parents().addBack().not('html')。each(function()){
var entry=this.tagName.toLowerCase();
if(this.className){
条目+=“+this.className.replace(//g'.');
}
右箭头。推送(输入);
});
警报(rightArrowParents.join(“”);
返回false;
});代码>
我将代码片段从T.J.Crowder移到了一个小小的jQuery插件上。我使用了他的jQuery版本,即使他是对的,这是完全不必要的开销,但我只将其用于调试目的,所以我不在乎
用法:
Html
$(".rightArrow")
.parents()
.map(function () {
var value = this.tagName.toLowerCase();
if (this.className) {
value += '.' + this.className.replace(' ', '.', 'g');
}
return value;
})
.get().reverse().join(", ");
存储库
这是一个返回jQuery路径的原生JS版本。我还为元素添加ID(如果它们有)。如果在数组中看到id,这将为您提供执行最短路径的机会
var path = getDomPath(element);
console.log(path.join(' > '));
输出
body > section:eq(0) > div:eq(3) > section#content > section#firehose > div#firehoselist > article#firehose-46813651 > header > h2 > span#title-46813651
下面是函数
function getDomPath(el) {
var stack = [];
while ( el.parentNode != null ) {
console.log(el.nodeName);
var sibCount = 0;
var sibIndex = 0;
for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
var sib = el.parentNode.childNodes[i];
if ( sib.nodeName == el.nodeName ) {
if ( sib === el ) {
sibIndex = sibCount;
}
sibCount++;
}
}
if ( el.hasAttribute('id') && el.id != '' ) {
stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
} else if ( sibCount > 1 ) {
stack.unshift(el.nodeName.toLowerCase() + ':eq(' + sibIndex + ')');
} else {
stack.unshift(el.nodeName.toLowerCase());
}
el = el.parentNode;
}
return stack.slice(1); // removes the html element
}
函数getDomPath(el){
var堆栈=[];
while(el.parentNode!=null){
控制台日志(el.nodeName);
var-sibCount=0;
var-sibIndex=0;
对于(var i=0;i1){
stack.unshift(el.nodeName.toLowerCase()+':eq(“+sibIndex+”);
}否则{
stack.unshift(el.nodeName.toLowerCase());
}
el=el.parentNode;
}
return stack.slice(1);//删除html元素
}
这里有一个元素精确匹配的解决方案
重要的是要理解,chrome工具显示的选择器(不是真正的选择器)并不能唯一地标识DOM中的元素。(例如,它不会区分连续span
元素的列表。没有定位/索引信息)
改编自
你可以这样使用它
console.log( $('some-selector').fullSelector() );
我需要一个本地JS版本,它返回CSS标准路径(不是jQuery),并处理ShadowDOM。此代码是Michael Connor答案的一个小更新,以防其他人需要:
function getDomPath(el) {
if (!el) {
return;
}
var stack = [];
var isShadow = false;
while (el.parentNode != null) {
// console.log(el.nodeName);
var sibCount = 0;
var sibIndex = 0;
// get sibling indexes
for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
var sib = el.parentNode.childNodes[i];
if ( sib.nodeName == el.nodeName ) {
if ( sib === el ) {
sibIndex = sibCount;
}
sibCount++;
}
}
// if ( el.hasAttribute('id') && el.id != '' ) { no id shortcuts, ids are not unique in shadowDom
// stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
// } else
var nodeName = el.nodeName.toLowerCase();
if (isShadow) {
nodeName += "::shadow";
isShadow = false;
}
if ( sibCount > 1 ) {
stack.unshift(nodeName + ':nth-of-type(' + (sibIndex + 1) + ')');
} else {
stack.unshift(nodeName);
}
el = el.parentNode;
if (el.nodeType === 11) { // for shadow dom, we
isShadow = true;
el = el.host;
}
}
stack.splice(0,1); // removes the html element
return stack.join(' > ');
}
函数getDomPath(el){
如果(!el){
返回;
}
var堆栈=[];
var isShadow=假;
while(el.parentNode!=null){
//控制台日志(el.nodeName);
var-sibCount=0;
var-sibIndex=0;
//获取同级索引
对于(var i=0;i您好此函数解决与路径中未显示的当前元素相关的错误 现在检查这个
$j(".wrapper").click(function(event) {
selectedElement=$j(event.target);
var rightArrowParents = [];
$j(event.target).parents().not('html,body').each(function() {
var entry = this.tagName.toLowerCase();
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}else if(this.id){
entry += "#" + this.id;
}
entry=replaceAll(entry,'..','.');
rightArrowParents.push(entry);
});
rightArrowParents.reverse();
//if(event.target.nodeName.toLowerCase()=="a" || event.target.nodeName.toLowerCase()=="h1"){
var entry = event.target.nodeName.toLowerCase();
if (event.target.className) {
entry += "." + event.target.className.replace(/ /g, '.');
}else if(event.target.id){
entry += "#" + event.target.id;
}
rightArrowParents.push(entry);
// }
其中$j
=jQuery变量
也可以用..来解决这个问题。。以类名
以下是替换函数:
function escapeRegExp(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
谢谢我一直在使用它,并对它做了一些改进
- 使用ES6语法
- 使用
而不是nth of type
,因为nth child
查找相同类型的子项,而不是任何子项nth of type
- 以更干净的方式删除
节点html
- 忽略具有
id
- 仅显示最近的
之前的路径(如果有)。这应该会使代码更具弹性,但如果您不希望出现这种行为,我在哪一行上留下了注释id
- 使用
处理ID和节点名称中的特殊字符CSS.escape
导出默认函数getDomPath(el){
常量堆栈=[]
while(el.parentNode!==null){
设sibCount=0
设sibIndex=0
for(设i=0;i0){
//:n类型为1索引
stack.unshift(`${nodeName}:nth类型(${sibIndex+1})`)
}否则{
堆栈取消移位(节点名)
}
el=el.parentNode
}
返回堆栈
}
几乎重复:请看这里Re.replace(“”,'g')
:标准JavaScript在字符串.prototype.replace函数上没有第三个参数;见本规范第15.5.4.11节
function getDomPath(el) {
var stack = [];
while ( el.parentNode != null ) {
console.log(el.nodeName);
var sibCount = 0;
var sibIndex = 0;
for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
var sib = el.parentNode.childNodes[i];
if ( sib.nodeName == el.nodeName ) {
if ( sib === el ) {
sibIndex = sibCount;
}
sibCount++;
}
}
if ( el.hasAttribute('id') && el.id != '' ) {
stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
} else if ( sibCount > 1 ) {
stack.unshift(el.nodeName.toLowerCase() + ':eq(' + sibIndex + ')');
} else {
stack.unshift(el.nodeName.toLowerCase());
}
el = el.parentNode;
}
return stack.slice(1); // removes the html element
}
var obj = $('#show-editor-button'),
path = '';
while (typeof obj.prop('tagName') != "undefined"){
if (obj.attr('class')){
path = '.'+obj.attr('class').replace(/\s/g , ".") + path;
}
if (obj.attr('id')){
path = '#'+obj.attr('id') + path;
}
path = ' ' +obj.prop('tagName').toLowerCase() + path;
obj = obj.parent();
}
console.log(path);
$.fn.fullSelector = function () {
var path = this.parents().addBack();
var quickCss = path.get().map(function (item) {
var self = $(item),
id = item.id ? '#' + item.id : '',
clss = item.classList.length ? item.classList.toString().split(' ').map(function (c) {
return '.' + c;
}).join('') : '',
name = item.nodeName.toLowerCase(),
index = self.siblings(name).length ? ':nth-child(' + (self.index() + 1) + ')' : '';
if (name === 'html' || name === 'body') {
return name;
}
return name + index + id + clss;
}).join(' > ');
return quickCss;
};
console.log( $('some-selector').fullSelector() );
function getDomPath(el) {
if (!el) {
return;
}
var stack = [];
var isShadow = false;
while (el.parentNode != null) {
// console.log(el.nodeName);
var sibCount = 0;
var sibIndex = 0;
// get sibling indexes
for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
var sib = el.parentNode.childNodes[i];
if ( sib.nodeName == el.nodeName ) {
if ( sib === el ) {
sibIndex = sibCount;
}
sibCount++;
}
}
// if ( el.hasAttribute('id') && el.id != '' ) { no id shortcuts, ids are not unique in shadowDom
// stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
// } else
var nodeName = el.nodeName.toLowerCase();
if (isShadow) {
nodeName += "::shadow";
isShadow = false;
}
if ( sibCount > 1 ) {
stack.unshift(nodeName + ':nth-of-type(' + (sibIndex + 1) + ')');
} else {
stack.unshift(nodeName);
}
el = el.parentNode;
if (el.nodeType === 11) { // for shadow dom, we
isShadow = true;
el = el.host;
}
}
stack.splice(0,1); // removes the html element
return stack.join(' > ');
}
$j(".wrapper").click(function(event) {
selectedElement=$j(event.target);
var rightArrowParents = [];
$j(event.target).parents().not('html,body').each(function() {
var entry = this.tagName.toLowerCase();
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}else if(this.id){
entry += "#" + this.id;
}
entry=replaceAll(entry,'..','.');
rightArrowParents.push(entry);
});
rightArrowParents.reverse();
//if(event.target.nodeName.toLowerCase()=="a" || event.target.nodeName.toLowerCase()=="h1"){
var entry = event.target.nodeName.toLowerCase();
if (event.target.className) {
entry += "." + event.target.className.replace(/ /g, '.');
}else if(event.target.id){
entry += "#" + event.target.id;
}
rightArrowParents.push(entry);
// }
function escapeRegExp(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
export default function getDomPath(el) {
const stack = []
while (el.parentNode !== null) {
let sibCount = 0
let sibIndex = 0
for (let i = 0; i < el.parentNode.childNodes.length; i += 1) {
const sib = el.parentNode.childNodes[i]
if (sib.nodeName === el.nodeName) {
if (sib === el) {
sibIndex = sibCount
break
}
sibCount += 1
}
}
const nodeName = CSS.escape(el.nodeName.toLowerCase())
// Ignore `html` as a parent node
if (nodeName === 'html') break
if (el.hasAttribute('id') && el.id !== '') {
stack.unshift(`#${CSS.escape(el.id)}`)
// Remove this `break` if you want the entire path
break
} else if (sibIndex > 0) {
// :nth-of-type is 1-indexed
stack.unshift(`${nodeName}:nth-of-type(${sibIndex + 1})`)
} else {
stack.unshift(nodeName)
}
el = el.parentNode
}
return stack
}