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.
.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 οnlοad="....">, 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:
var preloadCssImages = { 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