如何通过选择器获取父元素

问题描述 投票:0回答:12

示例:

<div someAttr="parentDiv. We need to get it from child.">
    <table>
        ...
        <td> <div id="myDiv"></div> </td>
        ...
    </table>
</div>

我想通过内部 div 元素(具有

myDiv
类的元素)中的某个选择器获取父级。

如何使用纯 JavaScript 实现这一目标,无需 jQuery

类似:

var div = document.getElementById('myDiv');
div.someParentFindMethod('some selector');
javascript dom
12个回答
358
投票

您可以在现代浏览器中使用

closest()

var div = document.querySelector('div#myDiv');
div.closest('div[someAtrr]');

使用对象检测提供 polyfill 或替代方法以向后兼容 IE。


47
投票

这是最基本的版本:

function collectionHas(a, b) { //helper function (see below)
    for(var i = 0, len = a.length; i < len; i ++) {
        if(a[i] == b) return true;
    }
    return false;
}
function findParentBySelector(elm, selector) {
    var all = document.querySelectorAll(selector);
    var cur = elm.parentNode;
    while(cur && !collectionHas(all, cur)) { //keep going up until you find a match
        cur = cur.parentNode; //go up
    }
    return cur; //will return null if not found
}

var yourElm = document.getElementById("yourElm"); //div in your original code
var selector = ".yes";
var parent = findParentBySelector(yourElm, selector);

44
投票

查找与给定选择器匹配的最接近的父元素(或元素本身)。还包括一个停止搜索的选择器,以防您知道应该停止搜索的共同祖先。

function closest(el, selector, stopSelector) {
  var retval = null;
  while (el) {
    if (el.matches(selector)) {
      retval = el;
      break
    } else if (stopSelector && el.matches(stopSelector)) {
      break
    }
    el = el.parentElement;
  }
  return retval;
}

8
投票

通过使用 querySelector()closest() 方法可以获取父元素。

  • querySelector()
    返回与 a 匹配的第一个元素 在文档中指定 CSS 选择器。

  • closest()
    在 DOM 树中搜索最近的元素 与指定的 CSS 选择器匹配。

使用示例

const element = document.querySelector('td')

console.log(element.closest('div'))
<div>
  <table>
    <tr>
      <td></td>
    </tr>
  </table>
</div>

如果需要选择多个元素,querySelectorAll() 是一个不错的选择。

  • querySelectorAll()
    以静态 NodeList 对象的形式返回文档中与指定 CSS 选择器匹配的所有元素。

要选择所需的元素,需要在

[]
内指定它,例如第二个元素为:
element[1]

在下面的示例中,

closest()
方法用于获取特定选定元素的父
<tr>
元素。

const el = document.querySelectorAll('td')

console.log(el[1].closest('tr'))
<div>
  <table>
    <tr id="1">
      <td> First text </td>
    </tr>
    <tr id="2">
      <td> Second text </td>
    </tr>
  </table>
</div>


2
投票

将 leech 的答案与 indexOf 一起使用(以支持 IE)

这是使用 leech 所说的,但使其适用于 IE(IE 不支持匹配):

function closest(el, selector, stopSelector) {
  var retval = null;
  while (el) {
    if (el.className.indexOf(selector) > -1) {
      retval = el;
      break
    } else if (stopSelector && el.className.indexOf(stopSelector) > -1) {
      break
    }
    el = el.parentElement;
  }
  return retval;
}

它并不完美,但如果选择器足够唯一,它就不会意外匹配到错误的元素。


2
投票

这是一个递归解决方案:

function closest(el, selector, stopSelector) {
  if(!el || !el.parentElement) return null
  else if(stopSelector && el.parentElement.matches(stopSelector)) return null
  else if(el.parentElement.matches(selector)) return el.parentElement
  else return closest(el.parentElement, selector, stopSelector)
}

2
投票

我想我会提供一个更强大的示例,也是用打字稿编写的,但它很容易转换为纯 JavaScript。该函数将使用“#my-element”之类的 ID 或“.my-class”类来查询父级,并且与其中一些答案不同的是,该函数将处理多个类。我发现我命名了一些类似的东西,所以上面的例子发现了错误的东西。

function queryParentElement(el:HTMLElement | null, selector:string) {
    let isIDSelector = selector.indexOf("#") === 0
    if (selector.indexOf('.') === 0 || selector.indexOf('#') === 0) {
        selector = selector.slice(1)
    }
    while (el) {
        if (isIDSelector) {
            if (el.id === selector) {
                return el
            }
        }
        else if (el.classList.contains(selector)) {
            return el;
        }
        el = el.parentElement;
    }
    return null;
}

按班级名称选择:

let elementByClassName = queryParentElement(someElement,".my-class")

按 ID 选择:

let elementByID = queryParentElement(someElement,"#my-element")


2
投票

这是使用递归获取具有特定类的父级的简单方法。你可以修改它来根据选择器进行切换,但原理是一样的:

function findParentByClass(child, parentClass) {
    let parent = child.parentElement;

    while(!(parent.className === parentClass)){
        parent = findParentByClass(child.parentElement, parentClass)
    }

    return parent;
}

0
投票

函数parent_by_selector的简单示例,它返回父级或null(没有选择器匹配):

function parent_by_selector(node, selector, stop_selector = 'body') {
  var parent = node.parentNode;
  while (true) {
    if (parent.matches(stop_selector)) break;
    if (parent.matches(selector)) break;
    parent = parent.parentNode; // get upper parent and check again
  }
  if (parent.matches(stop_selector)) parent = null; // when parent is a tag 'body' -> parent not found
  return parent;
};

0
投票
  /* --------------------------------------------------
    get a parent element by its id or classname

    [child] - the element were starting with
    [idOrClassName] - id or classname of parent element
                      were looking for
    ------------------------------------------------- */
 function getParent(child, idOrClassName = ""){

    while(child.tagName.toLowerCase() != "body"){
  
       // get the next parent up
      child = child.parentNode;
 
       // we reached body tag which means parent element with
       // class or id of [idOrClassName] not found so exit
      if(child.tagName.toLowerCase() == "body"){
         return false;
      }

       // if the id of this element = [idOrClassName] or .classList
       // of [child] contains [idOrClassName], weve found our element
      if((child.id == idOrClassName) || (child.classList.contains(idOrClassName))){
         return child;
      }
   }

 }

-3
投票

这是访问父ID的简单方法

document.getElementById("child1").parentNode;

将为您提供访问父级 div 的魔力。

<html>
<head>
</head>
<body id="body">
<script>
function alertAncestorsUntilID() {
var a = document.getElementById("child").parentNode;
alert(a.id);
}
</script>
<div id="master">
Master
<div id="child">Child</div>
</div>
<script>
alertAncestorsUntilID();
</script>
</body>
</html>

-4
投票
var base_element = document.getElementById('__EXAMPLE_ELEMENT__');
for( var found_parent=base_element, i=100; found_parent.parentNode && !(found_parent=found_parent.parentNode).classList.contains('__CLASS_NAME__') && i>0; i-- );
console.log( found_parent );
© www.soinside.com 2019 - 2024. All rights reserved.