Source: Preload Css hover Images with Javascript
Why we need to preload css hover images? It is for the userability. Why we need to preload css hover images by Javascript? It is easy to implement and maintenance. below is the sample css class for a image button.
{
background-image: url(../images/button.jpg);
}
.button:hover
{
background-image: url(../images/button_ro.jpg);
}
If you did not preload "button_ro.jpg", the button will disappear for a while untill the "button_ro.jpg" is loaded, when user mouse over the button.
Yes, you can hard code to preload the "button_ro.jpg" in <body onload="....">, but it is not a good idea, and It is hard to maintenance. So the idea is to use Javascript to preload the images and only the Hover images. So in this example it is only preload "button_ro.jpg".
How to achive this? The idea is use javascript to parse the css for current page, find the hover images and preload it. Below is the Javascript function:
imgUrls: [],
divPreImages: null,
Load: function() {
this.parseCSS(document.styleSheets);
},
InitPreImageDiv: function() {
this.divPreImages = document.createElement("div");
this.divPreImages.style.display = "none";
this.divPreImages.style.visibility = "hidden";
document.body.appendChild(this.divPreImages);
},
inArray: function( elem, array ) {
for ( var i = 0, length = array.length; i < length; i++ )
if ( array[ i ] === elem )
return i;
return -1;
},
parseCSS: function(sheets) {
var w3cImport =-1;
},
parseCSS: function(sheets) {
var w3cImport = false,
imported = [],
importedSrc = [],
baseURL;
var sheetIndex = sheets.length;
while(sheetIndex--){//loop through each stylesheet
var cssPile = '';//create large string of all css rules in sheet
var csshref = (sheets[sheetIndex].href) ? sheets[sheetIndex].href : 'window.location.href';
var baseURLarr = csshref.split('/');//split href at / to make array
baseURLarr.pop();//remove file path from baseURL array
baseURL = baseURLarr.join('/');//create base url for the images in this sheet (css file's dir)
if (baseURL) {
baseURL += '/'; //tack on a / if needed
}
if(sheets[sheetIndex].cssRules || sheets[sheetIndex].rules){
thisSheetRules = (sheets[sheetIndex].cssRules) ? //->>> http://www.quirksmode.org/dom/w3c_css.html
sheets[sheetIndex].cssRules : //w3
sheets[sheetIndex].rules; //ie
var ruleIndex = thisSheetRules.length;
while(ruleIndex--){
if(thisSheetRules[ruleIndex].style && thisSheetRules[ruleIndex].style.cssText){
var text = thisSheetRules[ruleIndex].style.cssText;
if(thisSheetRules[ruleIndex].selectorText.indexOf('hover') != -1) { //only add hover class....
if(text.toLowerCase().indexOf('url') != -1){ // only add rules to the string if you can assume, to find an image, speed improvement
cssPile += text; // thisSheetRules[ruleIndex].style.cssText instead of thisSheetRules[ruleIndex].cssText is a huge speed improvement
}
}
} else if(thisSheetRules[ruleIndex].styleSheet) {
imported.push(thisSheetRules[ruleIndex].styleSheet);
w3cImport = true;
}
}
}
//parse cssPile for image urls
var tmpImage = cssPile.match(/[^\("]+\.(gif|jpg|jpeg|png)/g);
//reg ex to get a string of between a "(" and a ".filename" / '"' for opera-bugfix
if(tmpImage){
var i = tmpImage.length;
while(i--){ // handle baseUrl here for multiple stylesheets in different folders bug
var imgSrc = (tmpImage[i].charAt(0) == '/' || tmpImage[i].match('://')) ? // protocol-bug fixed
tmpImage[i] :
baseURL + tmpImage[i];
if(this.inArray(imgSrc, this.imgUrls) == -1){
this.imgUrls.push(imgSrc);
}
}
}
if(!w3cImport && sheets[sheetIndex].imports && sheets[sheetIndex].imports.length) {
for(var iImport = 0, importLen = sheets[sheetIndex].imports.length; iImport < importLen; iImport++){
var iHref = sheets[sheetIndex].imports[iImport].href;
iHref = iHref.split('/');
iHref.pop();
iHref = iHref.join('/');
if (iHref) {
iHref += '/'; //tack on a / if needed
}
var iSrc = (iHref.charAt(0) == '/' || iHref.match('://')) ? // protocol-bug fixed
iHref :
baseURL + iHref;
importedSrc.push(iSrc);
imported.push(sheets[sheetIndex].imports[iImport]);
}
}
}//loop
if(imported.length){
parseCSS(imported, importedSrc);
return false;
}
if( this.imgUrls && this.imgUrls.length > 0 ) {
this.InitPreImageDiv();
this.loadImgs();
}
},
loadImgs: function(){
if(this.imgUrls && this.imgUrls.length){
for ( var i = 0, length = this.imgUrls.length; i < length; i++ )
{
var img = new Image(); //new img obj
img.src = this.imgUrls[i]; //set src either absolute or rel to css dir
this.divPreImages.appendChild(img);
}
}
}
};
How to use this:
just call: preloadCssImages.Load(); after your page loaded.
来源:https://www.cnblogs.com/isc00028/archive/2009/09/16/1568140.html