html 当有多个元素具有相同的ID值时,jQuery是如何工作的?

az31mfrm  于 2022-12-09  发布在  jQuery
关注(0)|答案(8)|浏览(265)

我从Google的AdWords网站获取数据,该网站有多个元素具有相同的id
您能否解释一下为什么以下3个问题没有得到相同的答案(2)?
Live Demo
于飞:

<div>
    <span id="a">1</span>
    <span id="a">2</span>
    <span>3</span>
</div>

JS:

$(function() {
    var w = $("div");
    console.log($("#a").length);            // 1 - Why?
    console.log($("body #a").length);       // 2
    console.log($("#a", w).length);         // 2
});
bxpogfeg

bxpogfeg1#

Having 2 elements with the same ID is not valid html according to the W3C specification.
When your CSS selector only has an ID selector (and is not used on a specific context), jQuery uses the native document.getElementById method, which returns only the first element with that ID.
However, in the other two instances, jQuery relies on the Sizzle selector engine (or querySelectorAll , if available), which apparently selects both elements. Results may vary on a per browser basis.
However, you should never have two elements on the same page with the same ID. If you need it for your CSS, use a class instead.
If you absolutely must select by duplicate ID, use an attribute selector:

$('[id="a"]');

Take a look at the fiddle: http://jsfiddle.net/P2j3f/2/

Note: if possible, you should qualify that selector with a type selector, like this:

$('span[id="a"]');

The reason for this is because a type selector is much more efficient than an attribute selector. If you qualify your attribute selector with a type selector, jQuery will first use the type selector to find the elements of that type, and then only run the attribute selector on those elements. This is simply much more efficient.

bybem2ql

bybem2ql2#

There should only be one element with a given id. If you're stuck with that situation, see the 2nd half of my answer for options.
How a browser behaves when you have multiple elements with the same id (illegal HTML) is not defined by specification. You could test all the browsers and find out how they behave, but it's unwise to use this configuration or rely on any particular behavior.
Use classes if you want multiple objects to have the same identifier.

<div>
    <span class="a">1</span>
    <span class="a">2</span>
    <span>3</span>
</div>

$(function() {
    var w = $("div");
    console.log($(".a").length);            // 2
    console.log($("body .a").length);       // 2
    console.log($(".a", w).length);         // 2
});

If you want to reliably look at elements with IDs that are the same because you can't fix the document, then you will have to do your own iteration as you cannot rely on any of the built in DOM functions.
You could do so like this:

function findMultiID(id) {
    var results = [];
    var children = $("div").get(0).children;
    for (var i = 0; i < children.length; i++) {
        if (children[i].id == id) {
            results.push(children[i]);
        }
    }
    return(results);
}

Or, using jQuery:

$("div *").filter(function() {return(this.id == "a");});

jQuery working example: http://jsfiddle.net/jfriend00/XY2tX/ .
As to Why you get different results, that would have to do with the internal implementation of whatever piece of code was carrying out the actual selector operation. In jQuery, you could study the code to find out what any given version was doing, but since this is illegal HTML, there is no guarantee that it will stay the same over time. From what I've seen in jQuery, it first checks to see if the selector is a simple id like #a and if so, just used document.getElementById("a") . If the selector is more complex than that and querySelectorAll() exists, jQuery will often pass the selector off to the built in browser function which will have an implementation specific to that browser. If querySelectorAll() does not exist, then it will use the Sizzle selector engine to manually find the selector which will have it's own implementation. So, you can have at least three different implementations all in the same browser family depending upon the exact selector and how new the browser is. Then, individual browsers will all have their own querySelectorAll() implementations. If you want to reliably deal with this situation, you will probably have to use your own iteration code as I've illustrated above.

dfddblmv

dfddblmv3#

jQuery's id selector only returns one result. The descendant and multiple selectors in the second and third statements are designed to select multiple elements. It's similar to:

Statement 1

var length = document.getElementById('a').length;

...Yields one result.

Statement 2

var length = 0;
for (i=0; i<document.body.childNodes.length; i++) {
    if (document.body.childNodes.item(i).id == 'a') {
        length++;
    }
}

...Yields two results.

Statement 3

var length = document.getElementById('a').length + document.getElementsByTagName('div').length;

...Also yields two results.

cczfrluj

cczfrluj4#

当我们有一个愚蠢的页面,其中有多个元素具有相同的ID时,我们如何获取所需的元素?如果我们使用'#duplicatedId',我们只获取第一个元素。要实现选择其他元素,您可以这样做:

$("[id=duplicatedId]")

您将获得一个集合,其中包含id=duplicatedId的所有元素。

azpvetkf

azpvetkf5#

id Selector jQuery page

  • 每个ID值在文档中只能使用一次。如果为多个元素分配了相同的ID,则使用该ID的查询将只选择DOM中第一个匹配的元素。但是,不应依赖此行为;包含多个使用相同ID的元素的文档无效。*

顽皮的Google。但是我听说他们甚至不关闭他们的<html><body>标签。问题是,为什么Misha的第二个和第三个查询返回2而不是1。

ukxgm1gy

ukxgm1gy6#

如果您有多个具有相同id或相同名称的元素,只需为这些元素分配相同的类,并通过索引访问它们,然后执行所需的操作。

<div>
        <span id="a" class="demo">1</span>
        <span id="a" class="demo">2</span>
        <span>3</span>
    </div>

简问:

$($(".demo")[0]).val("First span");
$($(".demo")[1]).val("Second span");
sqougxex

sqougxex7#

访问个别物料

<div id='a' data-options='{"url","www.google.com"}'>Google</div>
<div id='a' data-options='{"url","www.facebook.com"}'>Facebook</div>
<div id='a' data-options='{"url","www.twitter.com"}'>Twitter</div>

$( "div[id='a']" ).on('click', function() {
$(location).attr('href', $(this).data('options').url);
});
ktca8awb

ktca8awb8#

您可以直接写入$('span #a').length来取得长度。
下面是您的代码的解决方案:

console.log($('span#a').length);

试试JSfiddle:https://jsfiddle.net/vickyfor2007/wcc0ab5g/2/

相关问题