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

发布于 2024-09-09 09:20:17 字数 605 浏览 3 评论 0原文

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

想象一下

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

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

我正在考虑这样的系统:

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

我不知道该怎么做 3,期待暴力方法(在两个方向迭代并查看它是否存在)

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

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

感谢您的帮助/想法!

雷托

I'm looking for a nice way to mark/select all elements between two selected elements.

Imagine

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

There's a click handler on parent. The user now can select two p element in this list an then all p-elements in between should get 'activated'.

I'm thinking about a system like:

  1. first click: mark/remember first element -> A
  2. second click: mark/remember second element -> B
  3. determine whether or not A is before B
  4. do a A.nextUntil(B) (unless B is before A)

I have no idea how to do 3, expect the brute force approach (iterate in both directions and see if it is there)

  • Does the dom internally know what element comes before another?
  • Are there any nicer ideas?

About my situation: parent could contain several thousand p's.

Thanks for your help/ideas!

Reto

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南薇 2024-09-16 09:20:17

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

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

或者,一种稍微更快的方法:

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

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


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

是如何添加的?也许您可以为他们每个人提供一个与其位置相对应的 ID(例如 p1p2...)——这肯定会让您不必使用以上方法。

To determine which element comes first you could simply do:

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

Or, a slightly faster approach:

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

Note, both of these approaches will only work properly if a and b have the same parent.


About my situation: parent could contain several thousand p's.

How are the <p>s added? Maybe you could give them each an ID corresponding to their position (e.g. p1, p2...) -- this would definitely save you from having to determine their positions using the above approaches.

抱猫软卧 2024-09-16 09:20:17

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

您可以将其用作:

firstPara.compareDocumentPosition(otherPara);

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

还有一个 jQuery 插件

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

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

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

There is a method compareDocumentPosition defined in DOM level 3 to compare the position of two DOM nodes.

You would use it as:

firstPara.compareDocumentPosition(otherPara);

If the return value is 2 or Node.DOCUMENT_POSITION_PRECEDING, then firstPara comes before otherPara.

There is also a jQuery plugin for it.

I like @J-P's approach of adding some identifier to quickly determine their position without looking at any other elements. HTML5's data attributes are also an option for storing this value.

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

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

溇涏 2024-09-16 09:20:17

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

hey Reto here's a solution i cooked up in jquery, hope it helps:

 <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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文