Javascript 如果div包含所有指定的元素,请选择该div

Javascript 如果div包含所有指定的元素,请选择该div,javascript,jquery,html,jquery-selectors,Javascript,Jquery,Html,Jquery Selectors,我正在尝试选择包含tagOne和tagTwo跨度元素的.item div 我的部门结构如下: <div id="items"> <div id="block1" class="item"> <span class="tagOne tag">One</span> <span class="tagTwo tag">Two</span> </div> <

我正在尝试选择包含tagOne和tagTwo跨度元素的.item div

我的部门结构如下:

<div id="items">

    <div id="block1" class="item">
        <span class="tagOne tag">One</span>
        <span class="tagTwo tag">Two</span>
    </div>

    <div id="block2" class="item">
        <span class="tagOne tag">Java</span>
    </div>

</div>
然而,一旦我尝试将它们组合起来,将其缩小到包含它们的一个div,我就没有得到任何结果,而且我似乎也不知道为什么

blocks.filter('.item').find('[class*="tagOne"][class*="tagTwo"]');
我的理解是逗号语法将创建OR表达式,而不创建and表达式。我在寻找AND表达式,因为我只想返回包含所有条件的div,或者根本不返回任何条件

注意:我这样做是因为我正在基于标记和条件(即tagOne、tagTwo)创建一个切换过滤器,tagOne、tagTwo是未显示的用户选择的标记的串联,因此最好尝试在一个操作中完成

编辑:将重复id移到类名,使其有效,并相应地调整JavaScript代码

试试这个

 blocks.filter('.item').find('[id="tagOne"],[id="tagTwo"]');
首先,ID应该是唯一的。现在,标记包含两个ID为tagOne的元素,这是无效的标记

您可以使用类而不是ID

在本例中,从two.tagOne或.tagTwo中选择任意元素 用于选择具有其他类的同级元素 用于选择与选择器匹配的最近祖先。 上面的步骤1、2和3将仅选择同时具有.tagOne和.tagTwo作为子代的.item元素

代码:

$'.tagOne'//选择一个元素 .sibles'.tagTwo'//如果第二个元素是同级元素,则获取该元素 .closest'.item'//获取最近的祖先 .addClass“已选定”;//用于演示目的 .项目{ 颜色:红色; } 选定部门{ 颜色:绿色; } 一 二 JAVA 我喜欢JavaScript 如果选定节点具有某些子节点,请尝试使用has it搜索:

虽然您已经接受了答案,但我觉得这是一个值得使用普通JavaScript的问题,而不仅仅是一个jQuery解决方案。因此,考虑到这一点,我想提供以下方法,它确实使用了一些ECMAScript 6 feastures,因此需要一个相当现代的浏览器:

// using an Immediately-Invoked Function Expression syntax,
// so that the enclosed function will be executed when
// encountered, rather than requiring the user to call it
// explicitly (this would need to run in a DOMReady callback
// or once the DOM has been constructed, however):
(function hasAll(opts) {

  // setting the default settings for the function:
  var settings = {
    // a CSS Selector string to identify the ancestor
    // element that you wish to identify:
    'ancestorSelector': 'div',

    // an array of CSS Selectors to identify the
    // descendants by which the ancestor should
    // be found:
    'descendantSelectors': []
  }

  // looking at the named (not inherited) properties
  // of the opts Object supplied by the user:
  for (var property in opts) {

    // if the opts Object has a given property
    // name we set the corresponding property
    // of the settings Object to be equal to that
    // property-value:
    if (opts.hasOwnProperty(property)) {
      settings[property] = opts[property];
    }
  }

  // finding all the elements represented by the first selector
  // of the user-supplied selectors contained within an element
  // matching the ancestor selector:
  var firstElements = document.querySelectorAll(
      settings.ancestorSelector + ' ' + settings.descendantSelectors[0]
    ),

  // converting the NodeList returned by document.querySelectorAll()
  // into an Array, using Array.from:
    arrayOfFirsts = Array.from(firstElements),

  // here we iterate over that Array, using Array.prototype.filter():
    hasSiblings = arrayOfFirsts.filter(function(n) {

      // we look for the parentNode of the current node (n):
      var p = n.parentNode;

      // we use Array.prototype.every() to ensure that every
      // selector in the descendantSelectors Array returns
      // a Node (document.querySelector() returns only the
      // first node matching the given selector, or null if
      // there is no element matching that selector).
      // if Array.prototype.every() returns true (all elements
      // of the Array match the supplied test) then the current
      // node (n) is retained in the array returned by
      // Array.prototype.filter():
      return settings.descendantSelectors.every(function(selector) {

        // Array.prototype.every() returns a Boolean,
        // true : if all elements of the Array match
        //        the supplied test/assessment,
        // false: if *any* of the elements of the Array
        //        fail to match.
        // this is the test that we're matching against:
        return p.querySelector(selector) !== null;
      });
    });

  // here we iterate over the hasSiblings Array, and use
  // Array.prototype.map() to form a new Array, using
  // an Arrow function to take the current node (n)
  // and find, and return, the closest element to that
  // node which matches the supplied settings.ancestorSelector:
  var found = hasSiblings.map(n => n.closest(settings.ancestorSelector));

  // returning that array to the calling context:
  return found;

})({
  // this is the 'opts' Object that we're passing to the
  // IIFE-contained function:
  'ancestorSelector': '.item',
  'descendantSelectors': ['.tagOne', '[data-demo]']

// using Array.prototype.forEach() to iterate over the
// returned elements, to add the class 'hasAll' to the
// the classList (the list of class-names) of the given
// node (n):
}).forEach(n => n.classList.add('hasAll'));
函数hasAllopts{ 变量设置={ “取消存储选择器”:“div”, “后代选择器”:[] } 对于opts中的var属性{ if opts.hasOwnPropertyproperty{ 设置[属性]=选择[属性]; } } var firstElements=document.queryselectoral settings.anteStorSelector+''+settings.degenantSelectors[0] , arrayOfFirsts=Array.fromfirstElements, hasSiblings=arrayOfFirsts.FilterFunction{ var p=n.parentNode; 返回设置。后代选择器。everyfunctionselector{ 返回p.querySelectorselector!==null; }; }; var found=Array.from hasSiblings.mapn=>n.closestsettings.ancestorSelector; 发现退货; }{ “ancestorSelector':”.item', “后代选择器”:['.tagOne~.tagTwo'] }.forEachn=>n.classList.add'hasAll'; div{ 宽度:50%; 保证金:0.5em自动; 边框:2×000; 边界半径:1米; 填充:0.5em; 框大小:边框框; } 哈索尔先生{ 边框颜色:f90; } 哈索尔·斯潘先生{ 颜色:f90; 字体大小:粗体; } 一 二 JAVA 标记一 标签二 标签三
您必须使用,。blocks.filter'.item'.find'[id=tagOne],[id=tagTwo];当多个元素共享同一id时,JavaScript将无法可靠地工作,顺便说一句,这也会导致HTML无效。如果您需要有多个具有公共标识符的元素,那么您应该使用类名,而不是id。@DavidThomas谢谢,您是对的。我也会看看改变this@AnkitKathiriya我的理解是,逗号表示语法或语法,因此它将返回所有实例。我试图做的是返回包含所有必需元素的div,或者不返回任何您应该使用的类。并执行检查块。筛选'.item'.find'.tagOne.tagTwo';如果两个类都存在,那么它将返回。我不确定这是怎么回事,也不理解这个问题。但不管怎么说,你的尝试很好。第二次,我也是这么做的,不是吗?@PraveenKumar不!在代码中,您正在检查是否存在任何元素。>0。因此,即使存在任何一个元素,它也将返回true。@Smittey。您只需更改选择器的数组,代码就会相应地对元素进行归档。欢迎@Smittey。很高兴能帮忙:。我建议你删除这个答案。如果你认为这是可行的,添加一个现场演示。一个有趣的解决方案,谢谢!也很有魅力
$('.tagOne') // Select one of the element
  .siblings('.tagTwo') // Get second element if it is sibling
  .closest('.item') // Get the closest ancestor
// using an Immediately-Invoked Function Expression syntax,
// so that the enclosed function will be executed when
// encountered, rather than requiring the user to call it
// explicitly (this would need to run in a DOMReady callback
// or once the DOM has been constructed, however):
(function hasAll(opts) {

  // setting the default settings for the function:
  var settings = {
    // a CSS Selector string to identify the ancestor
    // element that you wish to identify:
    'ancestorSelector': 'div',

    // an array of CSS Selectors to identify the
    // descendants by which the ancestor should
    // be found:
    'descendantSelectors': []
  }

  // looking at the named (not inherited) properties
  // of the opts Object supplied by the user:
  for (var property in opts) {

    // if the opts Object has a given property
    // name we set the corresponding property
    // of the settings Object to be equal to that
    // property-value:
    if (opts.hasOwnProperty(property)) {
      settings[property] = opts[property];
    }
  }

  // finding all the elements represented by the first selector
  // of the user-supplied selectors contained within an element
  // matching the ancestor selector:
  var firstElements = document.querySelectorAll(
      settings.ancestorSelector + ' ' + settings.descendantSelectors[0]
    ),

  // converting the NodeList returned by document.querySelectorAll()
  // into an Array, using Array.from:
    arrayOfFirsts = Array.from(firstElements),

  // here we iterate over that Array, using Array.prototype.filter():
    hasSiblings = arrayOfFirsts.filter(function(n) {

      // we look for the parentNode of the current node (n):
      var p = n.parentNode;

      // we use Array.prototype.every() to ensure that every
      // selector in the descendantSelectors Array returns
      // a Node (document.querySelector() returns only the
      // first node matching the given selector, or null if
      // there is no element matching that selector).
      // if Array.prototype.every() returns true (all elements
      // of the Array match the supplied test) then the current
      // node (n) is retained in the array returned by
      // Array.prototype.filter():
      return settings.descendantSelectors.every(function(selector) {

        // Array.prototype.every() returns a Boolean,
        // true : if all elements of the Array match
        //        the supplied test/assessment,
        // false: if *any* of the elements of the Array
        //        fail to match.
        // this is the test that we're matching against:
        return p.querySelector(selector) !== null;
      });
    });

  // here we iterate over the hasSiblings Array, and use
  // Array.prototype.map() to form a new Array, using
  // an Arrow function to take the current node (n)
  // and find, and return, the closest element to that
  // node which matches the supplied settings.ancestorSelector:
  var found = hasSiblings.map(n => n.closest(settings.ancestorSelector));

  // returning that array to the calling context:
  return found;

})({
  // this is the 'opts' Object that we're passing to the
  // IIFE-contained function:
  'ancestorSelector': '.item',
  'descendantSelectors': ['.tagOne', '[data-demo]']

// using Array.prototype.forEach() to iterate over the
// returned elements, to add the class 'hasAll' to the
// the classList (the list of class-names) of the given
// node (n):
}).forEach(n => n.classList.add('hasAll'));