Problem with jQuery contains method selecting div and span element

问题: I have problem facing selecting div/span elements via jQuery contains(arg) method. I want to count the total number of elements that contain specific text. But it is giving...

问题:

I have problem facing selecting div/span elements via jQuery contains(arg) method. I want to count the total number of elements that contain specific text. But it is giving different results to different HTML elelemts. See the code below.

$(document).ready(function(){
	
  $("#co").text($("span:contains('cool')").length)
  $("#co1").text($("div:contains('cool')").length)
  $("#co2").text($("li:contains('cool')").length)
  $("#co3").text($("p:contains('cool')").length)
});
Span -<span id="co"> </span>
<div></div>
Div -<span id="co1"> </span>
<div></div>
Li -<span id="co2"> </span>
<div></div>
p -<span id="co3"> </span>
<br><br>

<div> <div> cool </div> </div>
<p> <p> cool </p> </p>
<ul><li> <li> cool </li> </li></ul>
<span> <span> cool </span> </span>

The above code outputs result

Span -2
Div -2
Li -1 
p -1 

I just don't understand WHY, while every element should have same count.


回答1:

To understand why, look at the rendered HTML. When you have a <p> inside another unclosed <p>, the browser things you meant to end the previous <p> and start a new one, because <p>s cannot nest. Similarly, a <li> cannot exist directly inside another <li> - it may only exist as a child of a <ul> (or <ol>), so <li> <li> cool </li> </li> gets interpreted as <li> </li><li> cool </li>.

On the other hand, <span>s and <div>s can be nested in each other, so they appear in the document the same way your HTML is written.

console.log(document.body.innerHTML);
<div> <div> cool </div> </div>
<p> <p> cool </p> </p>
<ul><li> <li> cool </li> </li></ul>
<span> <span> cool </span> </span>

So, the rendered document has:

  • <span> <span> cool </span> </span> - a cool nested inside 2 <span>s
  • <p> </p><p> cool </p> <p></p> - a cool nested inside one <p> (the other <p>s being empty)
  • <ul><li> </li><li> cool </li> </ul> - a cool nested inside one <li> (the other <li>s being empty)
  • <div> <div> cool </div> </div> - a cool nested inside 2 <div>s

回答2:

The reason your jQuery outputs unexpected counts of each element is that your HTML is invalid. When you have invalid HTML, the browser automatically tries to correct it for you, by moving / removing sections that it knows is invalid. If you look at the DOM, you'll see that several of your elements don't exist.

For example, <p> <p> cool </p> </p> produces the following during rendering:

p

In the above, you can see that indeed, only one <p> element contains cool, resulting in one match.

Fixing up the invalid HTML also displays the correct results:

$(document).ready(function() {
  $("#co").text($("span:contains('cool')").length)
  $("#co1").text($("div:contains('cool')").length)
  $("#co2").text($("li:contains('cool')").length)
  $("#co3").text($("p:contains('cool')").length)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Span -<span id="co"> </span>
<div></div>
Div -<span id="co1"> </span>
<div></div>
Li -<span id="co2"> </span>
<div></div>
p -<span id="co3"> </span>
<br><br>

<div>
  <div>cool</div>
</div>
<p>cool</p>
<ul>
  <li>cool</li>
</ul>
<span>cool</span>

  • 发表于 2019-07-05 17:53
  • 阅读 ( 199 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除