在我们书写html代码的时候,为了便于阅读,标签与标签之间常用空格、换行隔开,但是在IE8以后的浏览器包括现在的Chrome、opera等浏览器中,把节点与节点之间的空白符(即空格和换行)也视为文本节点。因为这个原因而产生出很多坑。下面盘点一下笔者碰到的。
- 最开始是实现li标签行内排列的时候碰上的
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <style type="text/css" media="screen"> * { margin: 0; padding: 0; } html { font-size: 62.5%; } nav { width: 100%; line-height: 3rem; background-color: blue; padding: 0 1.5rem; } ul { text-align: left; } li { display: inline-block; background-color: red; padding: 0 1.5rem; } </style> </head> <body> <nav> <ul> <li>登录</li> <li>关于</li> <li>注册</li> <li>帮助</li> <li>退出</li> </ul> </nav> </body> </html>复制代码
结果是这个样子的:
![18b19654c31481c75c511deffab5327c.png](https://img-blog.csdnimg.cn/img_convert/18b19654c31481c75c511deffab5327c.png)
这是因为在li换行的时候会产生一个空白符,并把它视为一个文本节点,且具有宽度。
2.第二次是用原生JS获取子节点时候
在JS中获取子节点有以下几种方法:
- firstElementChild
- firstChild
- childNodes
- children
我们通过一个例子来分析这几种方法的区别(获取div下的p标签)
![1ec5e128a2ec26607bf3349cfe387096.png](https://img-blog.csdnimg.cn/img_convert/1ec5e128a2ec26607bf3349cfe387096.png)
输出结果是这样的:
![be43a25ab38a423b0c968c8834dacd14.png](https://img-blog.csdnimg.cn/img_convert/be43a25ab38a423b0c968c8834dacd14.png)
#text就是因换行而产生的文本节点。
从上面这个例子可以看出firstElementChild和Children比较针对,只会返回指定元素里面的元素节点,文本节点和属性节点都不予理会,但firstElementChildren 在ie9以前不兼容,会返回undefined。
而firstChild、childNodes就厉害了,事无巨细,无论是元素、文本、属性啥都给你获取过来,所以上面那个例子里获取到的是空白符,所以使用这俩的时候要小心一些,最好使用Children来获取比较保险。
3.有一题面试题是这样的:使两个div,一行显示,宽度比例为40%、60%,要给出尽可能多的方案,其中一个方案就是
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #one { background-color: blue; width: 60%; } #two { background-color: red; width: 40%; } div { display: inline-block; height: 100px; } </style> </head> <body> <div id="one"></div><div id="two"></div> </body> </html>复制代码
用display: inline-block实现就一定要注意标签之间的空白符,如果不消除掉空白符,就会因宽度不够把第二个div挤到下一行去
注:另一个方案就是弹性布局,一个flex:2,另一个flex:3,欢迎在评论区中补充~
......
解决办法:
1.写html代码时,把所有li标签写在一行里,从根本上消除空白符,但是这样影响代码阅读,不易于后期维护。
<body> <nav> <ul> <li>登录</li><li>哈哈</li><li>嘿嘿</li><li>帮助</li><li>退出</li> </ul> </nav> </body>复制代码
2.这是一个很有意思的方式,就是li标签不闭合,让其自动补全,也是可以清除空白。
<body> <nav> <ul> <li>登录 <li>哈哈 <li>嘿嘿 <li>帮助 <li>退出 </ul> </nav> </body>复制代码
3.还可以给li标签一个负边距来抵消空白符的宽度,但是有一个缺点,就是空白符作为文本节点,其大小跟父节点ul标签有关,而ul标签又跟浏览器有关,所以负边距的大小不好确定。(一般是3像素)
margin-left:-3px;复制代码
4.既然空白符大小跟ul标签有关,那我们可以把ul标签的字体大小设置为0,再给li标签设置实际字体大小,这样就可以使空白符的大小为0。
<style> ul {font-size:0;} li {font-size : 1.2rem;} </style>复制代码
5.css4草案中有一个新增属性:white-space-collapsing,也可以解决这个问题,但是现在几乎没有浏览器支持,让我们展望未来吧。
作者:Gesangs