由锚点失效引发的hasLayout探究
来源:互联网 发布:计算机系网络pdf谢希仁 编辑:程序博客网 时间:2024/05/18 21:51
最近在项目中遇到了一些与锚点相关的问题,由此引出hasLayout的一系列概念和方法,在此记录下来与大家一起分享。
一、锚点的相关问题
1.html map定位的名字问题。
<div id="top"> <img src="img/20120417/top.jpg" alt="80后游戏" width="950" height="710" border="0" usemap="#map1" /> <map id="map1" name="map1"> <area coords="222,176,19" shape="circle" href="#bk01" title="超级玛丽"></area> <area coords="335,185,19" shape="circle" href="#bk02" title="三国志"></area> <area coords="443,163,19" shape="circle" href="#bk03" title="魂斗罗"></area> </map></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是内联元素,所以要使用宽高去触发,必须将其先转化为块级元素。
.jumpAnchor{ width:0; display:block;}
或者
.jumpAnchor{ height:0; display:inline-block;}
还有一个方法,就是直接在锚点所在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-height0;)。
三、IE6下PNG24/PNG32不透明的解决方法
说完了锚点和hasLayout,还有一个常见的问题。我们知道在所有浏览器下都可以支持透明的png8图片,但是有时候是出于清晰度的要求,有时候是为了去除杂边(当然,杂边的消除方式,可以采用ps中添加与背景色一致的杂色而达到目的,不过某些情况下这好像不太现实,比如背景色不是纯色的时候),我们不得不选用位数更高的透明图片,常用的png-24和png-32的。
.toTop a{ height:165px; width:216px; background:url("../img/20120417/gototop.png") no-repeat scroll 0 0 transparent; position:fixed; top:70%; right:1%; _position:absolute; _top:expression(documentElement.scrollTop + 350 + "px"); cursor:pointer; opacity:0.8; _background: none; /*针对IE6*/ _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=noscale, src="img/20120417/gototop.png");/*针对IE6*/ /*可以省略部分属性为_filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='img/20120417/gototop.png'); */}
相关的讲解:
style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/test.png')"
语法:
filter : progid:DXImageTransform.Microsoft.AlphaImageLoader ( enabled=bEnabled , sizingMethod=sSize , src=sURL )
enabled : 可选项。布尔值(Boolean)。设置或检索滤镜是否激活。 其中true : 默认值,滤镜激活。false : 滤镜被禁止。
sizingMethod : 可选项。字符串(String)。设置或检索滤镜作用的对象的图片在对象容器边界内的显示方式。
属性值:
crop : 剪切图片以适应对象尺寸。
image : 默认值。增大或减小对象的尺寸边界以适应图片的尺寸。
scale : 缩放图片以适应对象的尺寸边界。
src : 必选项。字符串(String)。使用绝对或相对 url 地址指定背景图像。假如忽略此参数,滤镜将不会作用。
属性值:
Enabled : 可读写。布尔值(Boolean)。参阅 enabled 属性。
sizingMethod : 可读写。字符串(String)。参阅 sizingMethod 属性。
src : 可读写。字符串(String)。参阅 src 属性。
说明:
在对象容器边界内,在对象的背景和内容之间显示一张图片。并提供对此图片的剪切和改变尺寸的操作。如果载入的是PNG(Portable Network Graphics)格式,则0%-100%的透明度也被提供。
PNG(Portable Network Graphics)格式的图片的透明度不妨碍你选择文本。也就是说,你可以选择显示在PNG(Portable Network Graphics)格式的图片完全透明区域后面的内容。
方法二:此方法针对直接插入html中的图片。对该图片定义css样式。注意,要准备一个透明的小图片transparent.gif,不要太大否则太大太多影响页面加载性能。此例子中是必须放在和html相同目录下。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>IE6下背景不透明解决办法</title><style type="text/css">.fixpng img {azimuth: expression(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none",this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "', sizingMethod='image')",this.src = "transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''),this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "', sizingMethod='crop')",this.runtimeStyle.backgroundImage = "none")),this.pngSet=true);}</style></head><body><div class="fixpng"><img src="1.png" width="10" height="10" border="0"/><img src="2.png" width="20" height="20" border="0" /><img src="3.png" width="30" height="30" border="0" /></div></body></html>
方法三:使用DD_belatedPNG插件,它不仅支持img,还支持backgrond-position与background-repeat.这是优于其他插件的功能.同时DD_belatedPNG还支持a:hover属性。
使用方法
1.下载DD_belatedPNG插件.下载地址http://dillerdesign.com/experiment/DD_belatedPNG/#download
2.在网页html中引用,如下:
<!--[if IE 6]> <script type="text/javascript" src="js/DD_belatedPNG_0.0.8a-min.js" ></script> <script type="text/javascript"> DD_belatedPNG.fix('#define,background'); </script><![endif]-->
说明:DD_belatedPNG.fix('CSS选择器, 应用类型');函数 DD_belatedPNG.fix() , 括号内参数分别为应用PNG的CSS选择器(支持ID选择器、类选择器)和应用类型(支持img和background两种)。
多个选择器多种类型的函数,可以连写为类似如 DD_belatedPNG.fix('#idname, .classname, .nav a:hover, img,background');
还有两种网络上的方法,未经测试,写在下面备用。
方法四:本方法也只对直接插入的图片有效,对背景图无效。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>IE6下png背景不透明解决办法</title><script language="JavaScript">function correctPNG() // correctly handle PNG transparency in Win IE 5.5 & 6.{ var arVersion = navigator.appVersion.split("MSIE") var version = parseFloat(arVersion[1]) if ((version >= 5.5) && (document.body.filters)) { for(var j=0; j<document.images.length; j++) { var img = document.images[j] var imgName = img.src.toUpperCase() if (imgName.substring(imgName.length-3, imgName.length) == "PNG") { var imgID = (img.id) ? "id='" + img.id + "' " : "" var imgClass = (img.className) ? "class='" + img.className + "' " : "" var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' " var imgStyle = "display:inline-block;" + img.style.cssText if (img.align == "left") imgStyle = "float:left;" + imgStyle if (img.align == "right") imgStyle = "float:right;" + imgStyle if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle var strNewHTML = "<span " + imgID + imgClass + imgTitle + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";" + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader" + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>" img.outerHTML = strNewHTML j = j-1 } } } }window.attachEvent("onload", correctPNG);</script><style type="text/css"><!--body {background-color: #9999CC;}--></style></head><body><img src="1.png" width="10" height="10" border="0"/><img src="2.png" width="20" height="20" border="0" /><img src="3.png" width="30" height="30" border="0" /></body></html>
方法五:纯js实现方法。
<script type="text/javascript">// 修复 IE 下 PNG 图片不能透明显示的问题function fixPNG(myImage) {var arVersion = navigator.appVersion.split("MSIE");var version = parseFloat(arVersion[1]);if ((version >= 5.5) && (version < 7) && (document.body.filters)){ var imgID = (myImage.id) ? "id='" + myImage.id + "' " : ""; var imgClass = (myImage.className) ? "class='" + myImage.className + "' " : ""; var imgTitle = (myImage.title) ? "title='" + myImage.title + "' " : "title='" + myImage.alt + "' "; var imgStyle = "display:inline-block;" + myImage.style.cssText; var strNewHTML = "<span " + imgID + imgClass + imgTitle + " style=\"" + "width:" + myImage.width + "px; height:" + myImage.height + "px;" + imgStyle + ";" + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader" + "(src=\'" + myImage.src + "\', sizingMethod='scale');\"></span>"; myImage.outerHTML = strNewHTML;} }window.onload=function(){ document.getElementById("top").style.height=screen.height/5+"px"; }//</script>
引用方法如下:
<img src="logo.png" width="" height="" border="0" onload="fixPNG(this)" />
更多相关文章请参考《你必须知道--IE中的hasLayout 》http://blog.csdn.net/rhinemetal/article/details/6233277
《最新让IE6支持PNG24背景透明最佳解决方法》http://hi.baidu.com/lzc10086/blog/item/ad38d32f645e82704ec22616.html
《IE6下png背景不透明问题的综合拓展》http://apps.hi.baidu.com/share/detail/34680089
- 由锚点失效引发的hasLayout探究
- 由锚点失效引发的hasLayout探究
- 由free()引发的对链表的探究(1)
- 由free()引发的对链表的探究(2)
- 一个由List.removeAll()失效引发的思考
- 指针引发的探究
- 由观影引发的几点人生思考
- 一次由点餐引发的 Vue2.0 实战
- c语言由一个小问题引发的关于gets和scanf的探究
- 由打开微信分享引发的activity任务栈属性探究
- 由fastlock引发的...
- 锚点失效的问题
- 探究requestDisallowInterceptTouchEvent失效的原因
- 由Typedef引发的问题
- 由InvocationTargetException引发的思考
- 由UseSubmitBehavior引发的问题
- 由BigDecimal引发的思考
- 由static引发的问题
- c和C++代码相互调用
- Deformable Probability Maps
- 在虚拟机中搭建svn 服务端
- Multiuser screen
- 设置对话框、static和group的背景色和字体颜色
- 由锚点失效引发的hasLayout探究
- 人体动作识别
- 状态无关特性
- 大端模式和小端模式
- 马尔科夫随机场
- 反编译
- WCF双程操作(心跳)
- 再谈“我是怎么招聘程序员的”
- PHP正则表达式经验