如何检测哪个元素包含所有其他X元素

时间:2016-08-22 14:45:39

标签: javascript jquery html

(希望这个问题尚未被提出:我没有通过关键字搜索找到它)

我想使用jQuery检测哪个元素(div,span,anything)包含所有其他XKindOfElement。

意思是,例如,如果我的屏幕中有多个复选框,我想知道哪个div包含所有这些复选框。

<div id="block1">
  <div id="underblock1">
    <input type="checkbox" name="thing[]" value="1" />
    <div id="underunderblock1">
      <input type="checkbox" name="thing[]" value="2" />
    </div>
  </div>
  <div id="underblock2">
    <input type="checkbox" name="thing[]" value="3" />
  </div>
</div>

在此示例中,它将返回div#block1,因为它只包含页面的所有input[type="checkbox"]

希望你能理解并帮助我!

更新

思考某事......你对这个过程有何看法:

  1. 检查页面中是否存在我们的元素
  2. 如果是,请计算这个元素的存在数量并保存(假设为count
  3. 检查第一个元素find的父元素是否包含所有count元素
  4. 如果没有,请检查父级的父级是否包含所有count元素
  5. 当选中的父级确实包含所有count元素时:它是我们“最小的全局父级”!
  6. 它是好还是太慢,太“膨胀”......?

4 个答案:

答案 0 :(得分:1)

我对所有jQuery助手方法都不太熟悉,但这种方法可能适合你:

  • 收集您想要包含的所有元素
  • 收集他们的parents数组并反转它们:所有这些数组现在都以:html > body开头并一直继续到实际元素
  • 循环访问父数组并检查其他父数组是否在当前索引处具有相同的元素
  • 不匹配的第一个元素标记最后一个共享父元素的索引

注意:您可能需要稍微重构一下代码,以确保您不会遇到边缘情况的任何错误。

&#13;
&#13;
var required = $("input[type=checkbox]");

var getClosestParent = function(elements) {
  var maxLength = 0;
  var allParents = [];

  elements.each(function(i, el) {
    var parents = $(el).parents().toArray().reverse();
    maxLength = Math.max(maxLength, parents.length);
    allParents.push(parents);
  });

  var ref = allParents[0];
  var others = allParents.slice(1);

  for (var i = 0; i < maxLength; i += 1) {
    for (var j = 0; j < others.length; j += 1) {
      if (ref[i] !== others[j][i]) {
        return ref[i - 1];
      }
    }
  }

  return null;
}

console.log(getClosestParent(required).id);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="block1">
  <div id="underblock1">
    <input type="checkbox" name="thing[]" value="1" />
    <div id="underunderblock1">
      <input type="checkbox" name="thing[]" value="2" />
    </div>
  </div>
  <div id="underblock2">
    <input type="checkbox" name="thing[]" value="3" />
  </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

为每个父项获取一个数组数组,然后循环遍历它们,直到找到未匹配项: -

var parents = new Array();
var minDepth = (Math.pow(2, 53) - 1);
$('[type=checkbox]').each(function(i, e) {
  parents.push($(e).parents().get().reverse());
  if (minDepth > parents[i].length)
    minDepth = parents[i].length;
});
var topParent, testParent;
finished:
  for (var i = 0; i < minDepth; i++) {
    testParent = parents[0][i];
    for (var j = 0; j < parents.length; j++) {
      if (parents[j][i] != testParent)
        break finished;
    }
    topParent = parents[0][i];
  }
console.log(topParent);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="block1">
  <div id="underblock1">
    <input type="checkbox" name="thing[]" value="1" />
    <div id="underunderblock1">
      <input type="checkbox" name="thing[]" value="2" />
    </div>
  </div>
  <div id="underblock2">
    <input type="checkbox" name="thing[]" value="3" />
  </div>
</div>

答案 2 :(得分:0)

好的,我正在向你们回答。我想@ user3297291说,但是我仍然认为从元素开始本身比从html > body > etc开始更快。

所以我这样做,你怎么看?

var required = jQuery("input[type=checkbox]");

var getClosestGlobalParent = function(elements) {
		var count = elements.length,
			result = null;
		if(count) { 
			if(count > 1) {
				jQuery(elements[0]).parents().each(function(i, el) {
					if(jQuery(this).find(elements).length == count) { 
						result = jQuery(this); // We also can return "this"
						return false; // If the parent is found, we stop the .each loop
					}
				});
			} else {
				result = jQuery(elements[0]).parent(); // If there's only one element, his closest parent IS his .parent()
			}
		}
		
		return result;
	}

	console.log(getClosestGlobalParent(required).attr('id'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
  <div id="under_container">
    <div id="block1">
      <div id="underblock1">
        <input type="checkbox" name="thing[]" value="1" /> Val1
        <div id="underunderblock1">
          <input type="checkbox" name="thing[]" value="2" /> Val2
        </div>
      </div>
      <div id="underblock2">
        <input type="checkbox" name="thing[]" value="3" /> Val3
        <br /><input type="checkbox" name="thing[]" value="4" /> Val4
      </div>
    </div>
   </div>
</div>

答案 3 :(得分:0)

$.fn.sharedParents = function(){
    if (this.length == 0)
        return this;

    var parents = $(this.get(0)).parents();
    for (var i=0; i<parents.length; i++)
        for (var j=1; j<this.length; j++)
            if (!$.contains(parents[i], this[j]))
            {
                delete parents[i];
                break;
            }

    return parents;
}

对于给定的元素集 - 获取第一个元素的所有父元素。然后,对于所有其他元素,检查给定的父项是否包含这些元素。结果是包含所有元素的所有父项的列表,因此,最深的父项将是该列表的第一个条目。

https://jsfiddle.net/hwte8n3w/