另一个jquery动态选择器

发布于 2024-09-15 19:01:20 字数 553 浏览 3 评论 0原文

我刚刚在这里问了一个关于选择 id_* 形式的所有 id 的问题,其中 * 是任何字符串,id 是元素的 id。我得到了一个很好的工作解决方案:

$("*[id^=" + id + "_]").each(function() {... // id is the element name

我现在需要更进一步: 我的所有 id 均采用以下形式:a_b_c ...,其中 ab 和 c 是任意字符串(不包含“”)。因此,现在不需要选择 id_* 形式的所有元素,其中 * 可以是 a_b_c ... 我只需要选择 1 层深度:即形式id_a。换句话说,它停在下一个“”处。这可能吗?

举个例子:

如果我的 id 是:first 并且存在 id:first_secondfirst_second_third 它将仅选择 first_second

I just asked a question here about selecting all id's of the form id_* where * is any string and id is the id of the element. I got a great working solution:

$("*[id^=" + id + "_]").each(function() {... // id is the element name

I need to take this one step further now:
All of my ids will be of the form: a_b_c ... where a b and c are arbitrarity strings (that do NOT contain a ''). So, now rather than selecting all the elems of the form id_* where * could be a_b_c ... I need only to select 1 level deep: i.e. all elems of the form id_a. So in other words it stops at the next ''. Is this possible?

As an example:

If my id is: first
And there exist id's: first_second, first_second_third
It will select only first_second

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

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

发布评论

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

评论(5

折戟 2024-09-22 19:01:20

听起来您在字段 id 中存储了太多值。在 HTML5 中,我们现在有了 data- 属性。

也许,您应该使用类似这样的 data- 属性来链接它们?

<div id="a">
</div>

<div id="b0" data-parentId='a'>
</div>

<div id="b1" data-parentId='a'>
</div>

<div id="b2" data-parentId='a'>
</div>

<div id="c" data-parentId='b1'>
</div>

它仍然会验证,因为任何以 data- 开头的非标准属性都将被视为有效。

请参阅:http://ejohn.org/blog/html-5-data-attributes /

然后,您的 jQuery 选择器可以使用这个新属性,而不是尝试解析字符串,

这样会选择 a 的所有子元素

var childrenOfA = $("div[data-parentId='a']);

Sounds like you are storing too many values in the id of the field. With HTML5 we now have data- attributes.

Perhaps, you should be making use of data- attributes something like this to link them?

<div id="a">
</div>

<div id="b0" data-parentId='a'>
</div>

<div id="b1" data-parentId='a'>
</div>

<div id="b2" data-parentId='a'>
</div>

<div id="c" data-parentId='b1'>
</div>

It will still validate, as any non-standard attribute starting with data- will be considered valid.

See: http://ejohn.org/blog/html-5-data-attributes/

Your jQuery selectors can then make use of this new attribute, rather than trying to parse strings

Something like this would select all of a's children

var childrenOfA = $("div[data-parentId='a']);
冷默言语 2024-09-22 19:01:20

我最终所做的(并且我愿意接受更快的实现)是:

$("*[id^=" + id + "_]").each(function() {
   //here I simply split the id and test the size of the array
   //if its too large (i.e. too deep in the tree), I return true (to continue
   //  to the next iteration):

   var row = $(this);
   var split = row.attr('id').split("_");

   if(split.length > SOME_PREDETERMINED_VAL)
      return true;

   //code here
});

我对此并不完全满意,因为它仍然遍历所有元素(或者无论each()函数中的过滤器如何,它都会这样做吗??) 。

What I ended up doing (and I'm open to faster implementations) is:

$("*[id^=" + id + "_]").each(function() {
   //here I simply split the id and test the size of the array
   //if its too large (i.e. too deep in the tree), I return true (to continue
   //  to the next iteration):

   var row = $(this);
   var split = row.attr('id').split("_");

   if(split.length > SOME_PREDETERMINED_VAL)
      return true;

   //code here
});

I am not totally happy with this since it still traverses all elements (or would it do this anyway regardless of the filter in the each() function??).

迷乱花海 2024-09-22 19:01:20

这并没有为您提供完整的解决方案,但您可以尝试 属性前缀选择器< /a> 或 属性以选择器开头

这将允许您选择元素的任何后代:

$("[id^='a_b_']").each(....

会考虑如何删除孙子等,但这可能会让您开始。

编辑

我刚刚发现有人提出了关于jQuery通配符 - 这看起来好像它可以满足您的需要。

This doesn't give you the whole solution, but you could try the attribute prefix selector or the attribute starts with selector

That will allow you to select any descendant of an element:

$("[id^='a_b_']").each(....

Will think how to remove the grandchildren etc, but this might get you started.

EDIT

I have just found that a similar question was asked about jQuery wildcards - this looks as if it will do what you need.

虚拟世界 2024-09-22 19:01:20

看来您使这项任务过于复杂化了。假设你的结构目前是这样的:

<div id="a">
    <div id="a_b">
        <div id="a_b_c">
        </div>
    </div>
</div>

为什么你不按照这些思路做一些事情...

<div id="a">
    <div class="b">
        <div class="c">
        </div>
    </div>
</div>

所以,如果我只是想要 #a .b 我会做:

$("#a .b").not("#a .c").show();  

让它更语义化并且可读。我明白你想做什么吗?可能需要更多地了解您到底在做什么

It seems like you are seriously overcomplicating this task. Let's say your structure is currently like this:

<div id="a">
    <div id="a_b">
        <div id="a_b_c">
        </div>
    </div>
</div>

Why don't you just do something along these lines...

<div id="a">
    <div class="b">
        <div class="c">
        </div>
    </div>
</div>

So, if I JUST wanted #a .b I would do:

$("#a .b").not("#a .c").show();  

Makes it a bit more semantic and readable as well. Am I understanding what you're trying to do? Might need to shed a bit more light on what exactly you're doing

半世蒼涼 2024-09-22 19:01:20

显而易见的解决方案是更改您的文档,例如,

<div id="a"></div>
<div id="a_b"></div>
<div id="a_b_c"></div>

您可以编写

<div id="a" class="l1"></div>
<div id="a_b" class="l2"></div>
<div id="a_b_c" class="l3"></div>

然后选择 $('.l2[id^=a_]')。如果这不是一个选项,您可以尝试某种筛选方案:(

var set = $('[id^='+id+'_]'), i = 0;
while (i < set.length) {
    var e = set.eq(i);
    if (e.attr('id').substr(id.length+1).match('_')) {
        set = set.not(e);
    } else {
        i++;
    }
    set = set.not($('[id^='+e.attr('id')+'_]'));
}

我还没有测试过,所以可能会出现错误,并且我不确定 not 是从结果集,但你明白了。)

这取决于文档结构和浏览器,这是否实际上比简单地遍历 while 集并跳过带有两个 _ 的所有内容的天真实现更快ID。 (每个节点的分支数量较多会有所帮助,并且在具有 jQuery 可以调用的 CSS3 前缀选择器本机实现的浏览器上可能会更快。)

更新: 修复了一些错误。逻辑可能会根据您的结构而变化,例如,如果 foo_bar 始终位于 foo_bar_baz 之前,则最里面的 if 分支是不必要的。

The obvious solution is changing your document, for example instead of

<div id="a"></div>
<div id="a_b"></div>
<div id="a_b_c"></div>

you could write

<div id="a" class="l1"></div>
<div id="a_b" class="l2"></div>
<div id="a_b_c" class="l3"></div>

and then select $('.l2[id^=a_]'). If that is not an option, you could try some sort of sieve scheme:

var set = $('[id^='+id+'_]'), i = 0;
while (i < set.length) {
    var e = set.eq(i);
    if (e.attr('id').substr(id.length+1).match('_')) {
        set = set.not(e);
    } else {
        i++;
    }
    set = set.not($('[id^='+e.attr('id')+'_]'));
}

(I haven't tested, so there might be errors, and I'm not sure not is the one that subtracts from a result set, but you get the idea.)

It depends on the document structure and browser whether this will be actually faster than the naive implmentation of simply walking through the while set and skipping everything with two _ in the id. (High number of branches per node helps, and it will be probably faster on browsers which have a native implementation of the CSS3 prefix selector which jQuery can call on.)

update: fixed some mistakes. The logic might change depending on your structure, e.g. the innermost if branch is unnecessery if foo_bar always precedes foo_bar_baz.

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