由锚点失效引发的hasLayout探究

╄→гoц情女王★ 提交于 2019-12-27 00:03:01

一、锚点的相关问题

 

1. html map定位的名字问题

 

1 <div id="top">  
2     <img src="img/top.jpg" alt="80后游戏" width="950" height="710" border="0" usemap="#map1" />  
3     <map id="map1" name="map1">  
4     <area coords="222,176,19"  shape="circle" href="#bk01" title="超级玛丽"></area>  
5     <area coords="335,185,19"  shape="circle" href="#bk02" title="三国志"></area>  
6     <area coords="443,163,19"  shape="circle" href="#bk03" title="魂斗罗"></area>  
7     </map>  
8 </div> 

 

大部分浏览器都支持map的name属性,而webkit内核的浏览器,如chrome和safari,不认识name,必须使用id,否则定位锚点消失。所以这里id和name都用。

 

2. 锚点的hasLayout问题

 

一般情况我们做页内导航都习惯用a标签,或者对图片采用map热点定位。然后设定一些锚点用于页面内部内容区块的快速定位,方便浏览者查找。为此需要 html中添加代码<a name="abc"></a>或<a id="abc"></a>,这样锚点就设好了。


不管是以a标签链接做导航,还是采用map area定位,其在IE6下锚点都可能存在bug,具体行为就是点击后没有跳转,无法定位。

 

个人认为这是IE6的Layout没有被触发,这里就需要手动添加CSS代码去激发hasLayout,这里是经过本人测试的几种办法,也是一些最常用的方法:


方法1.由于a是内联元素,所以要使用宽高去触发,必须将其先转化为块级元素。

 

1 .jumpAnchor{  
2     width:0;  
3     display:block;  
4 }  

或者

1 .jumpAnchor{  
2     height:0;  
3     display:inline-block;  
4 }

 

还有一个方法,就是直接在锚点所在a标签里添加文字或图片内容,让内容去撑开,自动去激发hasLayout。如<a id='anchor' name='anchor'>激发haslayout,我来撑开</a>


方法2.使用zoom:1;来触发,这个方法的副作用少,不用为此写许多兼容各浏览器的hack。这是目前为止最常用、最安全、最节约成本的激发方式。在个别复杂的情况下,可以搭配使用position:relative;来达到触发hasLayout的目的。

 

3. 锚点本身使用id与name属性的区别

 

1)二者的适用范围不同。目标元素的id和name都可以作为锚点,但name属性本身具有局限性,而id属性适用于任何类型的目标元素。这里列出name属性适用的几个标签元素:a, map, applet, form, frame, iframe, img


2)二者定位的准确性不同。某些情况下用id存在定位偏移,而name可以准确定位。虽然有解决id定位偏移的方法,但是如果仅仅是作为锚点,建议尽量使用name属性。


3)name属性可以重复而id不可重复,经测试重复的name和独立的id都会定位到第一个,但是为了养成良好的编码习惯,应该避免这样的写法,保持id和name属性值的唯一性。


此外,还需要注意,尽量对这两个属性使用小写字母。虽然html本身不区分大小写,但是对于锚点,在IE下不区分大小写,大写小写是一样的属性值,而在火狐Firefox、谷歌Chrome下大小写就属于两个不同的属性值了。

 

其实,我们在项目实践中,都经历过形形色色的hasLayout问题。而这些问题又有绝大部分是IE这个大魔头引出的,主要是IE6和IE7。比如设置 border边框显示边框断开,设置背景色不能正确显示,3px文本慢移,双边距,躲躲猫(peek-a-boo)。这些都是IE下面因此而生的bug。


插一句,IE6下面3px文本慢移出现的条件是:如果边框框邻近某浮动元素,则边框和浮动边缘之间会出现3px的间隙。在内容清除浮动之前,此间隙不会消 失,内容框朝着浮动相反的方向“慢移”三个像素。而当左对齐文本邻近右浮动时,可能难以看到此间隙,但它确实存在,而且它可能导致紧密的布局中出现“浮动 下降”。解决“3px文本慢移”的常用方法是:给浮动的盒子添加一个margin-right:-3px;(与浮动方向反方向)。

 

二、IE下hasLayout布局的触发机制

 

言归正转,为此,我们要认识hasLayout,了解它,然后才能更好的针对问题找出解决办法。

首先,我们要了解Layout与hasLayout属性是什么?


Layout,意为“布局”,是IE/Windows下的特有概念,它决定了元素如何对其内容进行定位和尺寸计算,与其他元素的关系和相互作用,以及对应 用还有使用者的影响。hasLayout为只读属性,对本身不具有Layout的元素,如果其Layout被动触发后是不可逆的。


hasLayout,是IE渲染引擎的一个内部组成部分。在IE中,一个元素计算大小和组织内容,要么对自身的内容进行计算大小和组织内容,要么依赖于父 元素来计算尺寸和组织内容。为了调节这两个不同的概念,渲染引擎采用了hasLayout的属性,属性值可以为true或false。当一个元素的 hasLayout属性值为true时,我们说这个元素有一个布局(Layout)。

据不完全统计,默认具有haslyout的HTML标签元素 有:<table>、<td>、<body>、<img>、<hr>、<input>、<select>、<textarea>、<button>、<iframe>、<embed>、<object> <applet>、<marquee>、< html>、< tr>、< th>、<fieldset>、< frameset>、<frame> 等。


当网页在IE中有异常表现时,可以首先通过尝试激发haslayout来确定是否为当前容器的Layout没有被激发造成。


接着,我们看如何来激发元素的hasLayout属性。以下是“寂寞贱客”


1、通过设置CSS能够获得的haslayout的属性有:display: inline-block;、height: (任何值除了auto);、float: (left或right);、position: absolute;、 width: (任何值除了auto);、writing-mode: tb-rl;、zoom: (除normal外任意值);、 min-height: (任意值);、 max-height: (除none外任意值);、min-width: (任意值);、max-width: (除none外任意值);、overflow: (除visible外任意值);、overflow-x: (除visible外任意值);、overflow-y: (除visible外任意值);、 position: fixed;(未完全统计)。


2、对于内联元素(默认即为内联的元素,如span,或display:inline; 的元素),width和height只在IE5.x下和IE6或更新版本的quirks模式下触发hasLayout。而对于IE6,如果浏览器运行于标 准兼容模式(具有Doctype的模式)下,内联元素会忽略width或height属性,所以设置width或height不能在此种情况下令该元素具 有layout。


3、zoom总是可以触发hasLayout,但是在IE5.0中不支持。


4、对IE6及更早版本来说,常用的方法被称为霍莉破解(Holly hack),即设定这个元素的height:1%;。需要注意的是,当这个元素的overflow属性为visible时,这个方法就失效了。曾经流行使 用这种方法的时候,还没有出现IE7,而height属性在IE6下其实是按照"min-height"来解析的,所以只要对IE6进行hack,"* html{height:1%}"就可以触发hasLayout,同时又不产生副作用。后来出现的IE7仍然存在很多hasLayout的问题,但IE7 已经能够正确识别height属性了,“height:1%”的方法已经不再适用了。


5、对IE7来说,最好的方法是设置元素的最小高度为0px(min-height:0;)。

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!