Javascript 获取所单击对象的DOM路径<;a>;

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

HTML

警告信息如下:

body div.lol a.rightArrow

如何使用javascript/jquery实现这一点?

使用jquery,如下所示(接下来是一个除事件外不使用jquery的解决方案;如果这很重要,则函数调用要少得多):

现场示例:

$(“.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;i1){ stack.unshift(nodeName+':第n个类型('+(sibIndex+1)+'); }否则{ 堆栈取消移位(nodeName); } el=el.parentNode; 如果(el.nodeType==11){//对于阴影dom,我们 isShadow=真; el=el.host; } } stack.splice(0,1);//删除html元素 返回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);
     // }
其中
$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
    之前的路径(如果有)。这应该会使代码更具弹性,但如果您不希望出现这种行为,我在哪一行上留下了注释
  • 使用
    CSS.escape
    处理ID和节点名称中的特殊字符
~

导出默认函数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
}