我正在尝试构建jQuery选择器,以“非贪婪”的方式将html元素与类“ widget”进行匹配,并且没有任何文档结构假设。我的意思是:不将内部子元素与相同的类匹配,也不关心小部件元素是否为直子。

我知道的唯一方法也是使用.not()选择器,例如:

$(".widget").not(".widget .widget");


但是通过这种方式,选择器无法再次在小部件内容中找到“子小部件”。

例如,给定此html:

<div class="otherClass">
    <h1>Some title</h1>
    <p>Some text...</h1>
    <div class="widget" id="w100">
        <div>
            <h2>Some intermediate level...</h2>
            <div class="widget" id="w110">
                <h2>Some title</h2>
                <div class="widget" id="w111">
                    ...
                </div>
                <div class="widget" id="w112">
                    ...
                </div>
            </div>
        </div>
        <div class="widget" id="w120">
            <h2>Some title</h2>
            <div class="widget" id="w121">
                ...
            </div>
            <div class="widget" id="w122">
                ...
            </div>
        </div>
    </div>
</div>


假设我要构建的选择器存储在选择器变量中,我想这样做:

var s0 = $(selector); // Matches div#w100 but not inner elements with "widget" class".
var s1 = $(selector, s0); // Matches div#w110 and div#w120
var s21 = $(selector, s1[0]); // Matches div#w111 and div#112
var s22 = $(selector, s1[1]); // Matches div#w121 and div#122


我的目标是基于适用于具有“小部件”分类的元素的小型控制器,实现一个简单的可嵌套小部件系统
和data-xxx属性中的其他参数来选择实际的窗口小部件控制器和参数。但是,小部件必须是ab
le在其html内容中散布其他子部件。

最佳答案

我对您的问题的解释与此处的其他人有所不同。在我看来,您想要的是从某个角度遍历DOM,搜索.widget,但不要在该类的任何元素下方递归。因此,如果您这样做:

var tops = $( /* some selector here*/ );


您需要顶级窗口小部件,如果执行此操作:

var next = $(tops[0]).find( /* some selector here*/ );


您想要第一个顶层小部件下面的第二层小部件,依此类推。

有一个插件可以做到这一点:

https://github.com/jstnjns/jquery-nearest

我将自由地在此处发布其代码:

(function() {

  $.fn.nearest = function(selector) {
    var $found = $(),
        checkChildren = function(filter) {
          var $children = this.children()
              $collection = $();

          $children.each(function() {
            var $matches = $(this).filter(filter),
                $fails = $(this).not(filter);

            if($matches.length) { $found = $found.add($matches); }

            if($fails.length) { checkChildren.call($fails, filter); }
          });
        };

    checkChildren.call(this, selector);

    return $found;
  }

}());


您可以这样使用:

var tops = $(document).nearest(".widget");
var next = $(tops[0]).nearest(".widget");

关于jquery - 非贪婪的jQuery选择器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30304927/

10-17 02:54