选择两个p元素之间的所有元素

时间:2010-07-13 09:12:54

标签: javascript jquery dom jquery-selectors

我正在寻找一种很好的方法来标记/选择两个选定元素之间的所有元素。

想象一下

<parent>
  <p>...</p>
  <p>...</p>
  <p>...</p>
  <p>...</p>
</parent>

父级上有一个点击处理程序。用户现在可以在此列表中选择两个p元素,然后中间的所有p元素都应该被“激活”。

我正在考虑一个类似的系统:

  1. 首先点击:标记/记住第一个元素 - &gt; A
  2. 第二次点击:标记/记住第二个元素 - &gt;乙
  3. 确定A是否在B
  4. 之前
  5. 做A.nextUntil(B)(除非B在A之前)
  6. 我不知道如何做3,期待蛮力方法(在两个方向迭代,看它是否在那里)

    • dom是否在内部知道哪个元素出现在另一个元素之前?
    • 有没有更好的想法?

    关于我的情况:父母可以包含几千个。

    感谢您的帮助/想法!

    雷托

3 个答案:

答案 0 :(得分:5)

要确定哪个元素首先出现,您可以执行以下操作:

$(a).index() < $(b).index()

或者,稍快一点的方法:

$(a).prevAll().length < $(b).prevAll().length

请注意,只有当ab具有相同的父级时,这两种方法才能正常运行。


  

关于我的情况:父母可以包含几千个。

如何添加<p>?也许你可以给每个人一个与他们的位置相对应的ID(例如p1p2 ...) - 这肯定会让你不必使用上述方法确定他们的位置。

答案 1 :(得分:1)

在DOM级别3中定义了一个方法compareDocumentPosition来比较两个DOM节点的位置。

您可以将其用作:

firstPara.compareDocumentPosition(otherPara);

如果返回值为2Node.DOCUMENT_POSITION_PRECEDING,则firstPara位于otherPara之前。

还有一个jQuery plugin

我喜欢@ J-P添加一些标识符以快速确定其位置而不查看任何其他元素的方法。 HTML5的数据属性也是存储该值的选项。

<parent>
  <p data-pos="1">..</p>
  <p data-pos="2">..</p>
  ..
</parent>

$(e).attr('data-pos')

进行访问

答案 2 :(得分:1)

嘿Reto这里是我在jquery中编写的解决方案,希望它有所帮助:

 <div id="test">
          <p>abc</p>
          <p>def</p>
          <p>ghi</p>
          <p>jkl</p>
        </div>

    <script>
    var a = $('#test').find('>p');
    var cli = [], range;
    $('#test').delegate("p",'click', function(event){
            if (cli.length < 2){//if there are less than 2 clicks in the queue
              cli.push(a.index(event.target));
            }
            else{//reset queue and recall the function
                cli = [];
                arguments.callee(event);
            }

            if (cli.length == 2){//if there are 2 clicks
             //filter from the initial selection only the elements between the two clicks
             range = a.filter(":lt("+cli[1]+"):gt("+cli[0]+")");
             if (cli[0]<cli[1]) {//aply some style to highlight and then revert
              range.css({color:'red'});
              setTimeout(function(){range.css({color:'black'})}, 1000);
          }
            }
    });
    </script>