javascript get element unique selector

时间:2017-02-12 04:50:29

标签: javascript

我正在使用javascript移动元素,我需要为拖放期间发生的组合创建逻辑

我正在尝试从元素中获取细节,像选择器这样的CSS也可以很好,但是如果可能的话就不知道..(就像chrome dev工具中的复制选择器一样)

document.onmouseup = function(e){
    targetDest = e.target;
    //console.log('targetDest: ', targetDest);

    let 
    indexA = Array.from(targetCurr.parentNode.children).indexOf(targetCurr),
    indexB = Array.from(targetDest.parentNode.children).indexOf(targetDest);

    console.log(indexA, indexB);


    if(targetDest != targetCurr){
        if(targetDest == document.documentElement){
            console.log('document');
        }
        else if(targetDest == undefined){
            console.log('undefined');
        }
        else if(!targetDest){
            console.log('!dest');
        }
        else if(targetDest == null){
            console.log('null');
        }
        else if(targetDest == false){
            console.log('false');
        }
        else{
            console.log('else');
            //targetCurr.parentNode.insertBefore(targetDest, targetCurr);

            //console.log('...');
        }
    }else{
        console.log('itself');
    }


}

3 个答案:

答案 0 :(得分:4)

请记住,这不一定唯一地标识元素。但是,您可以通过从节点向上遍历并预先添加您所在的元素来构造该类型的选择器。你可能会做这样的事情

var generateQuerySelector = function(el) {
      if (el.tagName.toLowerCase() == "html")
          return "HTML";
      var str = el.tagName;
      str += (el.id != "") ? "#" + el.id : "";
      if (el.className) {
          var classes = el.className.split(/\s/);
          for (var i = 0; i < classes.length; i++) {
              str += "." + classes[i]
          }
      }
      return generateQuerySelector(el.parentNode) + " > " + str;
}

var qStr = generateQuerySelector(document.querySelector("div.moo"));
alert(qStr);
body
<div class="outer">
  div.outer
  <div class="inner" id="foo">
    div#foo.inner
    <div class="moo man">
      div.moo.man
    </div>
  </div>
</div>

除了向用户提供信息之外,我不会建议使用它。将其拆分并重复使用部件必然会导致问题。

答案 1 :(得分:3)

我使用 :nth-child 的解决方案:

function getSelector(elm)
{
if (elm.tagName === "BODY") return "BODY";
const names = [];
while (elm.parentElement && elm.tagName !== "BODY") {
    if (elm.id) {
        names.unshift("#" + elm.getAttribute("id")); // getAttribute, because `elm.id` could also return a child element with name "id"
        break; // Because ID should be unique, no more is needed. Remove the break, if you always want a full path.
    } else {
        let c = 1, e = elm;
        for (; e.previousElementSibling; e = e.previousElementSibling, c++) ;
        names.unshift(elm.tagName + ":nth-child(" + c + ")");
    }
    elm = elm.parentElement;
}
return names.join(">");
}

var qStr = getSelector(document.querySelector("div.moo"));
alert(qStr);
body
<div class="outer">
  div.outer
  <div class="inner" id="foo">
    div#foo.inner
    <div class="moo man">
      div.moo.man
    </div>
  </div>
</div>

请注意,如果其中包含带有 ID 的元素,它不会返回整个路径 - 每个 ID 在页面上都应该是唯一的,因为有效的 HTML 要求。

我在代码后面的 document.querySelector 中使用了这个函数的输出,因为我需要在其父元素的 replaceChild 之后将焦点返回到同一个元素。

我希望 CollinD 不会介意我借用他的代码片段标记:-)

答案 2 :(得分:0)

我混合了提出的 2 个解决方案,以获得人类可读的结果,如果有几个类似的兄弟姐妹,它会给出正确的元素:

function elemToSelector(elem) {
  const {
    tagName,
    id,
    className,
    parentNode
  } = elem;

  if (tagName === 'HTML') return 'HTML';

  let str = tagName;

  str += (id !== '') ? `#${id}` : '';

  if (className) {
    const classes = className.split(/\s/);
    for (let i = 0; i < classes.length; i++) {
      str += `.${classes[i]}`;
    }
  }

  let childIndex = 1;

  for (let e = elem; e.previousElementSibling; e = e.previousElementSibling) {
    childIndex += 1;
  }

  str += `:nth-child(${childIndex})`;

  return `${elemToSelector(parentNode)} > ${str}`;
}

测试:

// Select an element in Elements tab of your navigator Devtools, or replace $0

document.querySelector(elemToSelector($0)) === $0 &&
document.querySelectorAll(elemToSelector($0)).length === 1

这可能会给你一些类似的东西,它有点长,但它是可读的,而且总是有效:

HTML > BODY:nth-child(2) > DIV.container:nth-child(2) > DIV.row:nth-child(2) > DIV.col-md-4:nth-child(2) > DIV.sidebar:nth-child(1) > DIV.sidebar-wrapper:nth-child(2) > DIV.my-4:nth-child(1) > H4:nth-child(3)

编辑:我刚刚找到包 unique-selector