继续上一部分,我们要看一下颜色。火狐好像不管三七二十一都会转变为rgb格式,不过我们通常比较习惯的是hex格式。这就用到以下两函数。
1.var rgb2hex = function(rgb) { 2. rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 3. return "#"+tohex(rgb[1])+tohex(rgb[2])+tohex(rgb[3]) 4.} 5.var tohex = function(x) { 6. var hexDigits = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']; 7. return isNaN(x) ? '00' : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16]; 8.}我们用正则表达式在检测其是否为rgb格式,是就用rgb2hex来转换它。但如果是red,green等值呢,火狐就一反常态,转换为hex格式,但IE依然如故。我们没有办法,自己做一个哈希,把常用的颜色都弄进去,然后一一匹对便是。
01.if(style.search(/background|color/) != -1) { 02. var color = { 03. aqua: '#0ff', 04. black: '#000', 05. blue: '#00f', 06. gray: '#808080', 07. purple: '#800080', 08. fuchsia: '#f0f', 09. green: '#008000', 10. lime: '#0f0', 11. maroon: '#800000', 12. navy: '#000080', 13. olive: '#808000', 14. orange:'#ffa500', 15. red: '#f00', 16. silver: '#c0c0c0', 17. teal: '#008080', 18. transparent:'rgba(0,0,0,0)', 19. white: '#fff', 20. yellow: '#ff0'21. } 22. if(!!color[value]){ 23. value = color[value] 24. } 25. if(value == "inherit"){ 26. return getStyle(el.parentNode,style); 27. } 28. if(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(value)){ 29. return rgb2hex(value) 30. }else if(/^#/.test(value)){ 31. value = value.replace('#', ''); 32. return "#" + (value.length == 3 ? value.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : value); 33. } 34. return value; 35.}基本上是对于CSS的精确取值就是这样,显然它还存在许多不足之处,但对于布局用的和常用的样式都实现了。还提供了一个判断页面渲染模式的常数q,为了方便,方法名与JQuery同名(只能取值,不能赋值,以后有空慢慢与我的addSheet函数整合到一起)。
001.(function(){ 002. var isQuirk = (document.documentMode) ? (document.documentMode==5) ? true : false : ((document.compatMode=="CSS1Compat") ? false : true); 003. var isElement = function(el) { 004. return !!(el && el.nodeType == 1); 005. } 006. var propCache = []; 007. var propFloat = !+"\v1" ? 'styleFloat' : 'cssFloat'; 008. var camelize = function(attr){ 009. return attr.replace(/\-(\w)/g, function(all, letter){ 010. return letter.toUpperCase(); 011. }); 012. } 013. var memorize = function(prop) { //意思为:check out form cache 014. return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : camelize(prop)); 015. } 016. var getIEOpacity = function(el){ 017. var filter; 018. if(!!window.XDomainRequest){ 019. filter = el.style.filter.match(/progid:DXImageTransform.Microsoft.Alpha\(.?opacity=(.*).?\)/i); 020. }else{ 021. filter = el.style.filter.match(/alpha\(opacity=(.*)\)/i); 022. } 023. if(filter){ 024. var value = parseFloat(filter[1]); 025. if (!isNaN(value)) { 026. return value ? value / 100 : 0; 027. } 028. } 029. return 1; 030. } 031. var convertPixelValue = function(el, value){ 032. var style = el.style,left = style.left,rsLeft = el.runtimeStyle.left; 033. el.runtimeStyle.left = el.currentStyle.left; 034. style.left = value || 0; 035. var px = style.pixelLeft; 036. style.left = left;//还原数据 037. el.runtimeStyle.left = rsLeft;//还原数据 038. return px + "px"039. } 040. var rgb2hex = function(rgb) { 041. rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); 042. return "#"+tohex(rgb[1])+tohex(rgb[2])+tohex(rgb[3]) 043. } 044. var tohex = function(x) { 045. var hexDigits = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']; 046. return isNaN(x) ? '00' : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16]; 047. } 048. var getStyle = function (el, style){ 049. var value; 050. if(!+"\v1"){ 051. //特殊处理IE的opacity 052. if(style == "opacity"){ 053. return getIEOpacity(el) 054. } 055. value = el.currentStyle[memorize(style)]; 056. //特殊处理IE的height与width 057. if (/^(height|width)$/.test(style)){ 058. var values = (style == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0; 059. if(isQuirk){ 060. return el[camelize("offset-"+style)] + "px"061. }else{ 062. var client = parseFloat(el[camelize("client-"+style)]), 063. paddingA = parseFloat(getStyle(el, "padding-"+ values[0])), 064. paddingB = parseFloat(getStyle(el, "padding-"+ values[1])); 065. return (client - paddingA - paddingB)+"px"; 066. } 067. } 068. }else{ 069. if(style == "float"){ 070. style = propFloat; 071. } 072. value = document.defaultView.getComputedStyle(el, null).getPropertyValue(style) 073. } 074. //下面部分全部用来转换上面得出的非精确值 075. if(!/^\d+px$/.test(value)){ 076. //转换可度量的值 077. if(/(em|pt|mm|cm|pc|in|ex|rem|vw|vh|vm|ch|gr)$/.test(value)){ 078. return convertPixelValue(el,value); 079. } 080. //转换百分比,不包括字体 081. if(/%$/.test(value) && style != "font-size"){ 082. return parseFloat(getStyle(el.parentNode,"width")) * parseFloat(value) /100 + "px"083. } 084. //转换border的thin medium thick 085. if(/^(border).+(width)$/.test(style)){ 086. var s = style.replace("width","style"), 087. b = { 088. thin:["1px","2px"], 089. medium:["3px","4px"], 090. thick:["5px","6px"] 091. }; 092. if(value == "medium" && getStyle(el,s) == "none"){ 093. return "0px"; 094. } 095. return !!window.XDomainRequest ? b[value][0] : b[value][1]; 096. } 097. //转换margin的auto 098. if(/^(margin).+/.test(style) && value == "auto"){ 099. var father = el.parentNode; 100. if(/MSIE 6/.test(navigator.userAgent) && getStyle(father,"text-align") == "center"){ 101. var fatherWidth = parseFloat(getStyle(father,"width")), 102. _temp = getStyle(father,"position"); 103. father.runtimeStyle.postion = "relative"; 104. var offsetWidth = el.offsetWidth; 105. father.runtimeStyle.postion = _temp; 106. return (fatherWidth - offsetWidth)/2 + "px"; 107. } 108. return "0px"; 109. } 110. //转换top|left|right|bottom的auto 111. if(/(top|left|right|bottom)/.test(style) && value == "auto"){ 112. return el.getBoundingClientRect()[style]; 113. } 114. //转换颜色 115. if(style.search(/background|color/) != -1) { 116. var color = { 117. aqua: '#0ff', 118. black: '#000', 119. blue: '#00f', 120. gray: '#808080', 121. purple: '#800080', 122. fuchsia: '#f0f', 123. green: '#008000', 124. lime: '#0f0', 125. maroon: '#800000', 126. navy: '#000080', 127. olive: '#808000', 128. orange:'#ffa500', 129. red: '#f00', 130. silver: '#c0c0c0', 131. teal: '#008080', 132. transparent:'rgba(0,0,0,0)', 133. white: '#fff', 134. yellow: '#ff0'135. } 136. if(!!color[value]){ 137. value = color[value] 138. } 139. if(value == "inherit"){ 140. return getStyle(el.parentNode,style); 141. } 142. if(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(value)){ 143. return rgb2hex(value) 144. }else if(/^#/.test(value)){ 145. value = value.replace('#', ''); 146. return "#" + (value.length == 3 ? value.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : value); 147. } 148. return value; 149. } 150. } 151. return value;//如 0px 152. } 153. var css = function(){ 154. var a = arguments; 155. if(a.length == 1){ 156. return getStyle(this,a[0]) 157. } 158. } 159. var _ = function(el){ 160. var el = isElement(el)? el :document.getElementById(el); 161. var gene = !el.constructor ? el : el.constructor.prototype; 162. gene.css = css; 163. gene.width = function(){ 164. return getStyle(this,"width"); 165. }; 166. gene.height = function(){ 167. return getStyle(this,"height"); 168. }; 169. return el 170. } 171. if(!window._){ //为了避免与JQuery的$发生冲突,我用_作为类库唯一的全局变量 172. window['_'] =_; 173. } 174. _.q = isQuirk; 175.})()用法如下:
1.window.onload = function(){ 2. alert(_("ccc").css("background-color")) 3. alert(_("aaa").css("width")) 4. alert(_(document.body).width()) 5.};我们可以用这个东西研究一下document.body与document.documentElement。
01.function text(){ 02. var body = document.body,html = document.documentElement; 03. _("w1").innerHTML = _(body).width(); 04. _("w2").innerHTML = _(html).width(); 05. _("h1").innerHTML = _(body).height(); 06. _("h2").innerHTML = _(html).height(); 07. _("ml1").innerHTML = _(body).css("margin-left"); 08. _("ml2").innerHTML = _(html).css("margin-left"); 09. _("mr1").innerHTML = _(body).css("margin-right"); 10. _("mr2").innerHTML = _(html).css("margin-right"); 11. _("mt1").innerHTML = _(body).css("margin-top"); 12. _("mt2").innerHTML = _(html).css("margin-top"); 13. _("mb1").innerHTML = _(body).css("margin-bottom"); 14. _("mb2").innerHTML = _(html).css("margin-bottom"); 15. _("pl1").innerHTML = _(body).css("padding-left"); 16. _("pl2").innerHTML = _(html).css("padding-left"); 17. _("pr1").innerHTML = _(body).css("padding-right"); 18. _("pr2").innerHTML = _(html).css("padding-right"); 19. _("bl1").innerHTML = _(body).css("border-left-width"); 20. _("bl2").innerHTML = _(html).css("border-left-width"); 21. _("br1").innerHTML = _(body).css("border-right-width"); 22. _("br2").innerHTML = _(html).css("border-right-width"); 23. _("qqq").innerHTML = !_.q ? "标准模式" : "怪癖模式"; 24. _("t1").innerHTML = _(body).css("top"); 25. _("t2").innerHTML = _(html).css("top"); 26. _("l1").innerHTML = _(body).css("left"); 27. _("l2").innerHTML = _(html).css("left"); 28. _("ot1").innerHTML = body.offsetTop; 29. _("ot2").innerHTML = html.offsetTop; 30. _("ol1").innerHTML = body.offsetLeft; 31. _("ol2").innerHTML = html.offsetLeft; 32. _("ct1").innerHTML = body.clientTop; 33. _("ct2").innerHTML = html.clientTop; 34. _("cl1").innerHTML = body.clientLeft; 35. _("cl2").innerHTML = html.clientLeft; 36. _("cw1").innerHTML = body.clientWidth; 37. _("cw2").innerHTML = html.clientWidth; 38. _("ow1").innerHTML = body.offsetWidth; 39. _("ow2").innerHTML = html.offsetWidth; 40. _("sw1").innerHTML = body.scrollWidth; 41. _("sw2").innerHTML = html.scrollWidth; 42.}在标准模式下,火狐等浏览器中我们看到offsetWidth等值最大为1007,因为火狐的offsetWidth不大于clientWidth,而clientWidth是不包含滚动条(滚动条的宽都固定为17px)。在IE中,offsetWidth是比clientWidth多了两个border,由此发现问题,1024-1003-17=4,4应该是两个auto生成,而这个auto应该为border的值,这两个border在IE中是固定死,不能通过以下手段修改。
1.<style type="text/css"> 2. html{ 3. border: 0; 4. } 5.</style>换言之,在标准模式下,IE的html是存在不可修改的宽为2px的border。也换言之,我的程序是有个BUG,没有正确显示出html的border为2px,囧。
再看怪癖模式,
| 测试属性 | document.body | document.documentElement |
|---|---|---|
| width | 1024px | 1024px |
| height | 604px | 604px |
| margin-left | 0px | undefined |
| margin-right | 0px | undefined |
| margin-top | 0px | undefined |
| margin-bottom | 0px | undefined |
| padding-left | 0px | 0px |
| padding-right | 0px | 0px |
| border-left-width | 4px | 0px |
| border-right-width | 4px | 0px |
| 渲染模式 | 怪癖模式 | |
| top | 0 | 0 |
| left | 0 | 0 |
| offsetTop | 0 | 0 |
| offsetLeft | 0 | 0 |
| clientTop | 2 | 0 |
| clientLeft | 2 | 0 |
| offsetWidth | 1024 | 1024 |
| clientWidth | 1003 | 0 |
| scrollWidth | 1003 | 1024 |
火狐等没有所谓的怪癖模式,直接看IE的。发现那神秘的2px又出现,这时出现在document.body的clientTop,clientLeft中。那么怪癖模式下的document.body的clientTop,clientLeft又相当于CSS的什么概念呢?我们来看微软给出的一幅老图,那时IE5独步天下,没有所谓标准模式与怪癖模式之分,因此这幅图的东西都是按怪癖模式表示的。

不难看出,clientLeft相当于borderLeft,clientTop相当于borderTop。至于上面的border-left-width与border-right-width,就不要看了,是错误,因为我当初就没有考虑这两个元素在标准模式与怪癖模式下的问题。既然document.body的边框区就达1024px了,那么html元素的脸往哪里搁呢?!对不起,在微软早期的设想,body元素才是代表文档(一个强有力的证据是,在怪癖模式下,网页的滚动条是位于body元素中)。模准模式连同火狐那帮失败者宣扬的各种没有市场份额的“标准”,都是在微软极不情愿下支持的。你看,documentElement这样累赘傻气的名字像是微软起的吗?!如果是微软,它应该就叫html,和document.boy那样简洁。搞到在标准模式下,我们取scrollLeft,要用document.
来源:http://www.cnblogs.com/rubylouvre/archive/2009/09/08/1562212.html
浙公网安备 33010602011771号