【问题标题】:Select all elements between two p-elements选择两个 p 元素之间的所有元素
【发布时间】:2010-07-13 09:12:54
【问题描述】:

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

想象一下

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

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

我正在考虑这样的系统:

  1. 第一次点击:标记/记住第一个元素 -> A
  2. 第二次点击:标记/记住第二个元素 -> B
  3. 判断A是否在B之前
  4. 执行 A.nextUntil(B)(除非 B 在 A 之前)

我不知道怎么做 3,期待蛮力方法(在两个方向上迭代,看看是否存在)

  • dom 内部是否知道哪个元素在另一个之前?
  • 还有更好的主意吗?

关于我的情况:父母可能包含数千个 p。

感谢您的帮助/想法!

重做

【问题讨论】:

  • 如果用户单击具有相同父级的元素,您的解决方案是可以的,但通常他们不会:-)
  • 感谢您的提示。我会确保:)。

标签: javascript jquery dom jquery-selectors


【解决方案1】:

要确定哪个元素先出现,您可以简单地这样做:

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

或者,稍微快一点的方法:

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

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


关于我的情况:父母可能包含数千个 p。

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

【讨论】:

  • 很有意思,但是你说 index() 比 prevAll().length 慢??
  • 我明白了,对于索引我必须选择所有元素.. Hm
  • 是的,index() 慢得多(请参阅this)——它在$(this).parent().children() 集合中执行indexOf 检查。 prevAll().length 更快。
  • 谢谢!我可能会采用 prevALl.length() 方法,直到我看到更多问题。如果发生这种情况,我会在加载 dom 后做一些索引,应该没问题:)。
  • +1 表示 ID 的建议。考虑到可能有数千个这样的情况,这将是一个实时的节省。
【解决方案2】:

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

您可以将其用作:

firstPara.compareDocumentPosition(otherPara);

如果返回值为2Node.DOCUMENT_POSITION_PRECEDING,则firstParaotherPara之前。

还有一个jQuery plugin

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

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

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

【讨论】:

    【解决方案3】:

    嘿,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>
    

    【讨论】:

      猜你喜欢
      • 2017-07-23
      • 2012-06-07
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      相关资源
      最近更新 更多