有关ie6下PNG图片背景不透明的一个js的解决办法
我们时常在使用png图片的时候,在ie6下发生背景不透明的问题,下面给大家介绍下一个js解决的方式。
首先我们要用到一个js,代码如下:
点击查看代码
1 /** 2 * DD_belatedPNG: Adds IE6 support: PNG images for CSS background-image and HTML <IMG/>. 3 * Author: Drew Diller 4 * Email: drew.diller@gmail.com 5 * URL: http://www.dillerdesign.com/experiment/DD_belatedPNG/ 6 * Version: 0.0.8a 7 * Licensed under the MIT License: http://dillerdesign.com/experiment/DD_belatedPNG/#license 8 * 9 * Example usage: 10 * DD_belatedPNG.fix('.png_bg'); // argument is a CSS selector 11 * DD_belatedPNG.fixPng( someNode ); // argument is an HTMLDomElement 12 **/ 13 14 /* 15 PLEASE READ: 16 Absolutely everything in this script is SILLY. I know this. IE's rendering of certain pixels doesn't make sense, so neither does this code! 17 */ 18 19 /** rewrite by waitingbar 2012.1.12 20 为了解决IE6下透明的png图片缩小时不能完全显示问题 21 el.vml.image.fill.type = 'tile'; 改为: 22 el.vml.image.fill.type = 'frame'; 23 */ 24 25 26 var DD_belatedPNG = { 27 ns: 'DD_belatedPNG', 28 imgSize: {}, 29 delay: 10, 30 nodesFixed: 0, 31 createVmlNameSpace: function () { /* enable VML */ 32 if (document.namespaces && !document.namespaces[this.ns]) { 33 document.namespaces.add(this.ns, 'urn:schemas-microsoft-com:vml'); 34 } 35 }, 36 createVmlStyleSheet: function () { /* style VML, enable behaviors */ 37 /* 38 Just in case lots of other developers have added 39 lots of other stylesheets using document.createStyleSheet 40 and hit the 31-limit mark, let's not use that method! 41 further reading: http://msdn.microsoft.com/en-us/library/ms531194(VS.85).aspx 42 */ 43 var screenStyleSheet, printStyleSheet; 44 screenStyleSheet = document.createElement('style'); 45 screenStyleSheet.setAttribute('media', 'screen'); 46 document.documentElement.firstChild.insertBefore(screenStyleSheet, document.documentElement.firstChild.firstChild); 47 if (screenStyleSheet.styleSheet) { 48 screenStyleSheet = screenStyleSheet.styleSheet; 49 screenStyleSheet.addRule(this.ns + '\\:*', '{behavior:url(#default#VML)}'); 50 screenStyleSheet.addRule(this.ns + '\\:shape', 'position:absolute;'); 51 screenStyleSheet.addRule('img.' + this.ns + '_sizeFinder', 'behavior:none; border:none; position:absolute; z-index:-1; top:-10000px; visibility:hidden;'); /* large negative top value for avoiding vertical scrollbars for large images, suggested by James O'Brien, http://www.thanatopsic.org/hendrik/ */ 52 this.screenStyleSheet = screenStyleSheet; 53 54 /* Add a print-media stylesheet, for preventing VML artifacts from showing up in print (including preview). */ 55 /* Thanks to R閙i Pr関ost for automating this! */ 56 printStyleSheet = document.createElement('style'); 57 printStyleSheet.setAttribute('media', 'print'); 58 document.documentElement.firstChild.insertBefore(printStyleSheet, document.documentElement.firstChild.firstChild); 59 printStyleSheet = printStyleSheet.styleSheet; 60 printStyleSheet.addRule(this.ns + '\\:*', '{display: none !important;}'); 61 printStyleSheet.addRule('img.' + this.ns + '_sizeFinder', '{display: none !important;}'); 62 } 63 }, 64 readPropertyChange: function () { 65 var el, display, v; 66 el = event.srcElement; 67 if (!el.vmlInitiated) { 68 return; 69 } 70 if (event.propertyName.search('background') != -1 || event.propertyName.search('border') != -1) { 71 DD_belatedPNG.applyVML(el); 72 } 73 if (event.propertyName == 'style.display') { 74 display = (el.currentStyle.display == 'none') ? 'none' : 'block'; 75 for (v in el.vml) { 76 if (el.vml.hasOwnProperty(v)) { 77 el.vml[v].shape.style.display = display; 78 } 79 } 80 } 81 if (event.propertyName.search('filter') != -1) { 82 DD_belatedPNG.vmlOpacity(el); 83 } 84 }, 85 vmlOpacity: function (el) { 86 if (el.currentStyle.filter.search('lpha') != -1) { 87 var trans = el.currentStyle.filter; 88 trans = parseInt(trans.substring(trans.lastIndexOf('=')+1, trans.lastIndexOf(')')), 10)/100; 89 el.vml.color.shape.style.filter = el.currentStyle.filter; /* complete guesswork */ 90 el.vml.image.fill.opacity = trans; /* complete guesswork */ 91 } 92 }, 93 handlePseudoHover: function (el) { 94 setTimeout(function () { /* wouldn't work as intended without setTimeout */ 95 DD_belatedPNG.applyVML(el); 96 }, 1); 97 }, 98 /** 99 * This is the method to use in a document. 100 * @param {String} selector - REQUIRED - a CSS selector, such as '#doc .container' 101 **/ 102 fix: function (selector) { 103 if (this.screenStyleSheet) { 104 var selectors, i; 105 selectors = selector.split(','); /* multiple selectors supported, no need for multiple calls to this anymore */ 106 for (i=0; i<selectors.length; i++) { 107 this.screenStyleSheet.addRule(selectors[i], 'behavior:expression(DD_belatedPNG.fixPng(this))'); /* seems to execute the function without adding it to the stylesheet - interesting... */ 108 } 109 } 110 }, 111 applyVML: function (el) { 112 el.runtimeStyle.cssText = ''; 113 this.vmlFill(el); 114 this.vmlOffsets(el); 115 this.vmlOpacity(el); 116 if (el.isImg) { 117 this.copyImageBorders(el); 118 } 119 }, 120 attachHandlers: function (el) { 121 var self, handlers, handler, moreForAs, a, h; 122 self = this; 123 handlers = {resize: 'vmlOffsets', move: 'vmlOffsets'}; 124 if (el.nodeName == 'A') { 125 moreForAs = {mouseleave: 'handlePseudoHover', mouseenter: 'handlePseudoHover', focus: 'handlePseudoHover', blur: 'handlePseudoHover'}; 126 for (a in moreForAs) { 127 if (moreForAs.hasOwnProperty(a)) { 128 handlers[a] = moreForAs[a]; 129 } 130 } 131 } 132 for (h in handlers) { 133 if (handlers.hasOwnProperty(h)) { 134 handler = function () { 135 self[handlers[h]](el); 136 }; 137 el.attachEvent('on' + h, handler); 138 } 139 } 140 el.attachEvent('onpropertychange', this.readPropertyChange); 141 }, 142 giveLayout: function (el) { 143 el.style.zoom = 1; 144 if (el.currentStyle.position == 'static') { 145 el.style.position = 'relative'; 146 } 147 }, 148 copyImageBorders: function (el) { 149 var styles, s; 150 styles = {'borderStyle':true, 'borderWidth':true, 'borderColor':true}; 151 for (s in styles) { 152 if (styles.hasOwnProperty(s)) { 153 el.vml.color.shape.style[s] = el.currentStyle[s]; 154 } 155 } 156 }, 157 vmlFill: function (el) { 158 if (!el.currentStyle) { 159 return; 160 } else { 161 var elStyle, noImg, lib, v, img, imgLoaded; 162 elStyle = el.currentStyle; 163 } 164 for (v in el.vml) { 165 if (el.vml.hasOwnProperty(v)) { 166 el.vml[v].shape.style.zIndex = elStyle.zIndex; 167 } 168 } 169 el.runtimeStyle.backgroundColor = ''; 170 el.runtimeStyle.backgroundImage = ''; 171 noImg = true; 172 if (elStyle.backgroundImage != 'none' || el.isImg) { 173 if (!el.isImg) { 174 el.vmlBg = elStyle.backgroundImage; 175 el.vmlBg = el.vmlBg.substr(5, el.vmlBg.lastIndexOf('")')-5); 176 } 177 else { 178 el.vmlBg = el.src; 179 } 180 lib = this; 181 if (!lib.imgSize[el.vmlBg]) { /* determine size of loaded image */ 182 img = document.createElement('img'); 183 lib.imgSize[el.vmlBg] = img; 184 img.className = lib.ns + '_sizeFinder'; 185 img.runtimeStyle.cssText = 'behavior:none; position:absolute; left:-10000px; top:-10000px; border:none; margin:0; padding:0;'; /* make sure to set behavior to none to prevent accidental matching of the helper elements! */ 186 imgLoaded = function () { 187 this.width = this.offsetWidth; /* weird cache-busting requirement! */ 188 this.height = this.offsetHeight; 189 lib.vmlOffsets(el); 190 }; 191 img.attachEvent('onload', imgLoaded); 192 img.src = el.vmlBg; 193 img.removeAttribute('width'); 194 img.removeAttribute('height'); 195 document.body.insertBefore(img, document.body.firstChild); 196 } 197 el.vml.image.fill.src = el.vmlBg; 198 noImg = false; 199 } 200 el.vml.image.fill.on = !noImg; 201 el.vml.image.fill.color = 'none'; 202 el.vml.color.shape.style.backgroundColor = elStyle.backgroundColor; 203 el.runtimeStyle.backgroundImage = 'none'; 204 el.runtimeStyle.backgroundColor = 'transparent'; 205 }, 206 /* IE can't figure out what do when the offsetLeft and the clientLeft add up to 1, and the VML ends up getting fuzzy... so we have to push/enlarge things by 1 pixel and then clip off the excess */ 207 vmlOffsets: function (el) { 208 var thisStyle, size, fudge, makeVisible, bg, bgR, dC, altC, b, c, v; 209 thisStyle = el.currentStyle; 210 size = {'W':el.clientWidth+1, 'H':el.clientHeight+1, 'w':this.imgSize[el.vmlBg].width, 'h':this.imgSize[el.vmlBg].height, 'L':el.offsetLeft, 'T':el.offsetTop, 'bLW':el.clientLeft, 'bTW':el.clientTop}; 211 fudge = (size.L + size.bLW == 1) ? 1 : 0; 212 /* vml shape, left, top, width, height, origin */ 213 makeVisible = function (vml, l, t, w, h, o) { 214 vml.coordsize = w+','+h; 215 vml.coordorigin = o+','+o; 216 vml.path = 'm0,0l'+w+',0l'+w+','+h+'l0,'+h+' xe'; 217 vml.style.width = w + 'px'; 218 vml.style.height = h + 'px'; 219 vml.style.left = l + 'px'; 220 vml.style.top = t + 'px'; 221 }; 222 makeVisible(el.vml.color.shape, (size.L + (el.isImg ? 0 : size.bLW)), (size.T + (el.isImg ? 0 : size.bTW)), (size.W-1), (size.H-1), 0); 223 makeVisible(el.vml.image.shape, (size.L + size.bLW), (size.T + size.bTW), (size.W), (size.H), 1 ); 224 bg = {'X':0, 'Y':0}; 225 if (el.isImg) { 226 bg.X = parseInt(thisStyle.paddingLeft, 10) + 1; 227 bg.Y = parseInt(thisStyle.paddingTop, 10) + 1; 228 } 229 else { 230 for (b in bg) { 231 if (bg.hasOwnProperty(b)) { 232 this.figurePercentage(bg, size, b, thisStyle['backgroundPosition'+b]); 233 } 234 } 235 } 236 el.vml.image.fill.position = (bg.X/size.W) + ',' + (bg.Y/size.H); 237 bgR = thisStyle.backgroundRepeat; 238 dC = {'T':1, 'R':size.W+fudge, 'B':size.H, 'L':1+fudge}; /* these are defaults for repeat of any kind */ 239 altC = { 'X': {'b1': 'L', 'b2': 'R', 'd': 'W'}, 'Y': {'b1': 'T', 'b2': 'B', 'd': 'H'} }; 240 if (bgR != 'repeat' || el.isImg) { 241 c = {'T':(bg.Y), 'R':(bg.X+size.w), 'B':(bg.Y+size.h), 'L':(bg.X)}; /* these are defaults for no-repeat - clips down to the image location */ 242 if (bgR.search('repeat-') != -1) { /* now let's revert to dC for repeat-x or repeat-y */ 243 v = bgR.split('repeat-')[1].toUpperCase(); 244 c[altC[v].b1] = 1; 245 c[altC[v].b2] = size[altC[v].d]; 246 } 247 if (c.B > size.H) { 248 c.B = size.H; 249 } 250 el.vml.image.shape.style.clip = 'rect('+c.T+'px '+(c.R+fudge)+'px '+c.B+'px '+(c.L+fudge)+'px)'; 251 } 252 else { 253 el.vml.image.shape.style.clip = 'rect('+dC.T+'px '+dC.R+'px '+dC.B+'px '+dC.L+'px)'; 254 } 255 }, 256 figurePercentage: function (bg, size, axis, position) { 257 var horizontal, fraction; 258 fraction = true; 259 horizontal = (axis == 'X'); 260 switch(position) { 261 case 'left': 262 case 'top': 263 bg[axis] = 0; 264 break; 265 case 'center': 266 bg[axis] = 0.5; 267 break; 268 case 'right': 269 case 'bottom': 270 bg[axis] = 1; 271 break; 272 default: 273 if (position.search('%') != -1) { 274 bg[axis] = parseInt(position, 10) / 100; 275 } 276 else { 277 fraction = false; 278 } 279 } 280 bg[axis] = Math.ceil( fraction ? ( (size[horizontal?'W': 'H'] * bg[axis]) - (size[horizontal?'w': 'h'] * bg[axis]) ) : parseInt(position, 10) ); 281 if (bg[axis] % 2 === 0) { 282 bg[axis]++; 283 } 284 return bg[axis]; 285 }, 286 fixPng: function (el) { 287 el.style.behavior = 'none'; 288 var lib, els, nodeStr, v, e; 289 if (el.nodeName == 'BODY' || el.nodeName == 'TD' || el.nodeName == 'TR') { /* elements not supported yet */ 290 return; 291 } 292 el.isImg = false; 293 if (el.nodeName == 'IMG') { 294 if(el.src.toLowerCase().search(/\.png$/) != -1) { 295 el.isImg = true; 296 el.style.visibility = 'hidden'; 297 } 298 else { 299 return; 300 } 301 } 302 else if (el.currentStyle.backgroundImage.toLowerCase().search('.png') == -1) { 303 return; 304 } 305 lib = DD_belatedPNG; 306 el.vml = {color: {}, image: {}}; 307 els = {shape: {}, fill: {}}; 308 for (v in el.vml) { 309 if (el.vml.hasOwnProperty(v)) { 310 for (e in els) { 311 if (els.hasOwnProperty(e)) { 312 nodeStr = lib.ns + ':' + e; 313 el.vml[v][e] = document.createElement(nodeStr); 314 } 315 } 316 el.vml[v].shape.stroked = false; 317 el.vml[v].shape.appendChild(el.vml[v].fill); 318 el.parentNode.insertBefore(el.vml[v].shape, el); 319 } 320 } 321 el.vml.image.shape.fillcolor = 'none'; /* Don't show blank white shapeangle when waiting for image to load. */ 322 //el.vml.image.fill.type = 'tile'; /* Makes image show up. */ 323 el.vml.image.fill.type = 'frame'; /* 2012.1.12 */ 324 el.vml.color.fill.on = false; /* Actually going to apply vml element's style.backgroundColor, so hide the whiteness. */ 325 lib.attachHandlers(el); 326 lib.giveLayout(el); 327 lib.giveLayout(el.offsetParent); 328 el.vmlInitiated = true; 329 lib.applyVML(el); /* Render! */ 330 } 331 }; 332 try { 333 document.execCommand("BackgroundImageCache", false, true); /* TredoSoft Multiple IE doesn't like this, so try{} it */ 334 } catch(r) {} 335 DD_belatedPNG.createVmlNameSpace(); 336 DD_belatedPNG.createVmlStyleSheet();
下面我们来看怎么使用这个js:
DD_belatedPNG是一款完美解决IE6下的PNG透明JS插件,DD_belatedPNG使用了微软的VML语言对PNG图片进行重新绘制,以达到半透明的效果,并且能支持background-position和background-repeat属性,支持伪类。在众多的ie6下png透明问题上,DD_belatedPNG是最好的解决方案,其它的都有很多负作用。
使用方法:
< !--[if IE 6]><script src="DD_belatedPNG.js"></script><script> DD_belatedPNG.fix('.png_bg');</script><![endif]-->
引用函数是DD_belatedPNG.fix(),括号里的 *表示所有css选择器.png_bg 改成你的css选择器名称。