代码
//
IE5.5+ PNG Alpha Fix v2.0 Alpha: Background Tiling Support
// (c) 2008 Angus Turnbull http://www.twinhelix.com
// This is licensed under the GNU LGPL, version 2.1 or later.
// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
var IEPNGFix = window.IEPNGFix || {};
IEPNGFix.tileBG = function (elm, pngSrc, ready) {
// Params: A reference to a DOM element, the PNG src file pathname, and a
// hidden "ready-to-run" passed when called back after image preloading.
var data = this .data[elm.uniqueID],
elmW = Math.max(elm.clientWidth, elm.scrollWidth),
elmH = Math.max(elm.clientHeight, elm.scrollHeight),
bgX = elm.currentStyle.backgroundPositionX,
bgY = elm.currentStyle.backgroundPositionY,
bgR = elm.currentStyle.backgroundRepeat;
// Cache of DIVs created per element, and image preloader/data.
if ( ! data.tiles) {
data.tiles = {
elm: elm,
src: '' ,
cache: [],
img: new Image(),
old: {}
};
}
var tiles = data.tiles,
pngW = tiles.img.width,
pngH = tiles.img.height;
if (pngSrc) {
if ( ! ready && pngSrc != tiles.src) {
// New image? Preload it with a callback to detect dimensions.
tiles.img.onload = function () {
this .onload = null ;
IEPNGFix.tileBG(elm, pngSrc, 1 );
};
return tiles.img.src = pngSrc;
}
} else {
// No image?
if (tiles.src) ready = 1 ;
pngW = pngH = 0 ;
}
tiles.src = pngSrc;
if ( ! ready && elmW == tiles.old.w && elmH == tiles.old.h &&
bgX == tiles.old.x && bgY == tiles.old.y && bgR == tiles.old.r) {
return ;
}
// Convert English and percentage positions to pixels.
var pos = {
top: ' 0% ' ,
left: ' 0% ' ,
center: ' 50% ' ,
bottom: ' 100% ' ,
right: ' 100% '
},
x,
y,
pc;
x = pos[bgX] || bgX;
y = pos[bgY] || bgY;
if (pc = x.match( / (\d+)% / )) {
x = Math.round((elmW - pngW) * (parseInt(pc[ 1 ]) / 100 ));
}
if (pc = y.match( / (\d+)% / )) {
y = Math.round((elmH - pngH) * (parseInt(pc[ 1 ]) / 100 ));
}
x = parseInt(x);
y = parseInt(y);
// Handle backgroundRepeat.
var repeatX = { ' repeat ' : 1 , ' repeat-x ' : 1 }[bgR],
repeatY = { ' repeat ' : 1 , ' repeat-y ' : 1 }[bgR];
if (repeatX) {
x %= pngW;
if (x > 0 ) x -= pngW;
}
if (repeatY) {
y %= pngH;
if (y > 0 ) y -= pngH;
}
// Go!
this .hook.enabled = 0 ;
if ( ! ({ relative: 1 , absolute: 1 }[elm.currentStyle.position])) {
elm.style.position = ' relative ' ;
}
var count = 0 ,
xPos,
maxX = repeatX ? elmW : x + 0.1 ,
yPos,
maxY = repeatY ? elmH : y + 0.1 ,
d,
s,
isNew;
if (pngW && pngH) {
for (xPos = x; xPos < maxX; xPos += pngW) {
for (yPos = y; yPos < maxY; yPos += pngH) {
isNew = 0 ;
if ( ! tiles.cache[count]) {
tiles.cache[count] = document.createElement( ' div ' );
isNew = 1 ;
}
var clipR = (xPos + pngW > elmW ? elmW - xPos : pngW),
clipB = (yPos + pngH > elmH ? elmH - yPos : pngH);
d = tiles.cache[count];
s = d.style;
s.behavior = ' none ' ;
s.left = xPos + ' px ' ;
s.top = yPos + ' px ' ;
s.width = clipR + ' px ' ;
s.height = clipB + ' px ' ;
s.clip = ' rect( ' +
(yPos < 0 ? 0 - yPos : 0 ) + ' px, ' +
clipR + ' px, ' +
clipB + ' px, ' +
(xPos < 0 ? 0 - xPos : 0 ) + ' px) ' ;
s.display = ' block ' ;
if (isNew) {
s.position = ' absolute ' ;
s.zIndex = - 999 ;
if (elm.firstChild) {
elm.insertBefore(d, elm.firstChild);
} else {
elm.appendChild(d);
}
}
this .fix(d, pngSrc, 0 );
count ++ ;
}
}
}
while (count < tiles.cache.length) {
this .fix(tiles.cache[count], '' , 0 );
tiles.cache[count ++ ].style.display = ' none ' ;
}
this .hook.enabled = 1 ;
// Cache so updates are infrequent.
tiles.old = {
w: elmW,
h: elmH,
x: bgX,
y: bgY,
r: bgR
};
};
IEPNGFix.update = function () {
// Update all PNG backgrounds.
for ( var i in IEPNGFix.data) {
var t = IEPNGFix.data[i].tiles;
if (t && t.elm && t.src) {
IEPNGFix.tileBG(t.elm, t.src);
}
}
};
IEPNGFix.update.timer = 0 ;
if (window.attachEvent && ! window.opera) {
window.attachEvent( ' onresize ' , function () {
clearTimeout(IEPNGFix.update.timer);
IEPNGFix.update.timer = setTimeout(IEPNGFix.update, 100 );
});
}
// (c) 2008 Angus Turnbull http://www.twinhelix.com
// This is licensed under the GNU LGPL, version 2.1 or later.
// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
var IEPNGFix = window.IEPNGFix || {};
IEPNGFix.tileBG = function (elm, pngSrc, ready) {
// Params: A reference to a DOM element, the PNG src file pathname, and a
// hidden "ready-to-run" passed when called back after image preloading.
var data = this .data[elm.uniqueID],
elmW = Math.max(elm.clientWidth, elm.scrollWidth),
elmH = Math.max(elm.clientHeight, elm.scrollHeight),
bgX = elm.currentStyle.backgroundPositionX,
bgY = elm.currentStyle.backgroundPositionY,
bgR = elm.currentStyle.backgroundRepeat;
// Cache of DIVs created per element, and image preloader/data.
if ( ! data.tiles) {
data.tiles = {
elm: elm,
src: '' ,
cache: [],
img: new Image(),
old: {}
};
}
var tiles = data.tiles,
pngW = tiles.img.width,
pngH = tiles.img.height;
if (pngSrc) {
if ( ! ready && pngSrc != tiles.src) {
// New image? Preload it with a callback to detect dimensions.
tiles.img.onload = function () {
this .onload = null ;
IEPNGFix.tileBG(elm, pngSrc, 1 );
};
return tiles.img.src = pngSrc;
}
} else {
// No image?
if (tiles.src) ready = 1 ;
pngW = pngH = 0 ;
}
tiles.src = pngSrc;
if ( ! ready && elmW == tiles.old.w && elmH == tiles.old.h &&
bgX == tiles.old.x && bgY == tiles.old.y && bgR == tiles.old.r) {
return ;
}
// Convert English and percentage positions to pixels.
var pos = {
top: ' 0% ' ,
left: ' 0% ' ,
center: ' 50% ' ,
bottom: ' 100% ' ,
right: ' 100% '
},
x,
y,
pc;
x = pos[bgX] || bgX;
y = pos[bgY] || bgY;
if (pc = x.match( / (\d+)% / )) {
x = Math.round((elmW - pngW) * (parseInt(pc[ 1 ]) / 100 ));
}
if (pc = y.match( / (\d+)% / )) {
y = Math.round((elmH - pngH) * (parseInt(pc[ 1 ]) / 100 ));
}
x = parseInt(x);
y = parseInt(y);
// Handle backgroundRepeat.
var repeatX = { ' repeat ' : 1 , ' repeat-x ' : 1 }[bgR],
repeatY = { ' repeat ' : 1 , ' repeat-y ' : 1 }[bgR];
if (repeatX) {
x %= pngW;
if (x > 0 ) x -= pngW;
}
if (repeatY) {
y %= pngH;
if (y > 0 ) y -= pngH;
}
// Go!
this .hook.enabled = 0 ;
if ( ! ({ relative: 1 , absolute: 1 }[elm.currentStyle.position])) {
elm.style.position = ' relative ' ;
}
var count = 0 ,
xPos,
maxX = repeatX ? elmW : x + 0.1 ,
yPos,
maxY = repeatY ? elmH : y + 0.1 ,
d,
s,
isNew;
if (pngW && pngH) {
for (xPos = x; xPos < maxX; xPos += pngW) {
for (yPos = y; yPos < maxY; yPos += pngH) {
isNew = 0 ;
if ( ! tiles.cache[count]) {
tiles.cache[count] = document.createElement( ' div ' );
isNew = 1 ;
}
var clipR = (xPos + pngW > elmW ? elmW - xPos : pngW),
clipB = (yPos + pngH > elmH ? elmH - yPos : pngH);
d = tiles.cache[count];
s = d.style;
s.behavior = ' none ' ;
s.left = xPos + ' px ' ;
s.top = yPos + ' px ' ;
s.width = clipR + ' px ' ;
s.height = clipB + ' px ' ;
s.clip = ' rect( ' +
(yPos < 0 ? 0 - yPos : 0 ) + ' px, ' +
clipR + ' px, ' +
clipB + ' px, ' +
(xPos < 0 ? 0 - xPos : 0 ) + ' px) ' ;
s.display = ' block ' ;
if (isNew) {
s.position = ' absolute ' ;
s.zIndex = - 999 ;
if (elm.firstChild) {
elm.insertBefore(d, elm.firstChild);
} else {
elm.appendChild(d);
}
}
this .fix(d, pngSrc, 0 );
count ++ ;
}
}
}
while (count < tiles.cache.length) {
this .fix(tiles.cache[count], '' , 0 );
tiles.cache[count ++ ].style.display = ' none ' ;
}
this .hook.enabled = 1 ;
// Cache so updates are infrequent.
tiles.old = {
w: elmW,
h: elmH,
x: bgX,
y: bgY,
r: bgR
};
};
IEPNGFix.update = function () {
// Update all PNG backgrounds.
for ( var i in IEPNGFix.data) {
var t = IEPNGFix.data[i].tiles;
if (t && t.elm && t.src) {
IEPNGFix.tileBG(t.elm, t.src);
}
}
};
IEPNGFix.update.timer = 0 ;
if (window.attachEvent && ! window.opera) {
window.attachEvent( ' onresize ' , function () {
clearTimeout(IEPNGFix.update.timer);
IEPNGFix.update.timer = setTimeout(IEPNGFix.update, 100 );
});
}