כתבתי קוד לתיקון png על IE, שעובד עם css expression. לא – אין מה לדאוג, לא מדובר ב-css expression שירוץ כל אירוע שקורה בעמוד, אלא רק פעם אחת עבור כל תמונה או אלמנט עם class=png. בנוסף, ישנה תמיכה בשינוי תמונה בצורה דינמית.
img,.png {
behavior:expression((function () {
window.__isPng=window.__isPng || function (src) { return src.toLowerCase().indexOf('.png')>-1; };
window.__fixPng=window.__fixPng || function (el) {
var pngSource,sizingMethod;
if (el.nodeName.toLowerCase()=="img" && window.__isPng(el.src)) {
pngSource=el.src;
sizingMethod="image";
el.src="transparent.gif";
} else if (window.__isPng(el.currentStyle.backgroundImage)) {
pngSource=el.currentStyle.backgroundImage.replace('url("','').replace('")','');
sizingMethod=el.currentStyle.backgroundRepeat=="no-repeat" ? "crop" : "scale";
el.runtimeStyle.backgroundImage="none";
}
if (pngSource) el.runtimeStyle.filter="progid:DXImageTransform.Microsoft.AlphaImage"+"Loader(src='"+pngSource+"', sizingMethod='"+sizingMethod+"')";
};
this.runtimeStyle.behavior="none";
var that=this;
this.attachEvent("onpropertychange",function (e) {
if (e.propertyName=="src") window.__fixPng(that);
});
window.__fixPng(this);
}).call(this));
}
קצת הסברים:
css expression, יכול להכיל קוד javascript לכל דבר. ההתייחסות ל-this בתוכו, היא התייחסות לאלמנט עצמו. לא מומלץ להשתמש בו מאחר והוא יפעל בכל אירוע בדפדפן. ראו כאן. בהמשך אסביר איך השימוש שלי לגיטימי.
בפונקציה window.__isPng אנחנו נגלה האם path של תמונה מכיל png.
הפונקציה window.__fixPng מקבלת אלמנט, בודקת אם הוא מסוג תמונה או כל אלמנט אחר, בהתאמה בודקת את ה-src או ה-background-image שלו ומחילה עליו filter של AlphaImageLoader. כאשר מדובר בתמונה, נאלץ להשאיר לה src כדי לא להחליף אותה באלמנט אחר. לשם כך נשתמש בתמונה המכילה gif שקוף של פיקסל.
היות הביטוי x=x || function אומר – x שווה ל-x או לפונקציה. ה-או אומר, אם האיבר הראשון הינו שווה ערך ל-false (שזה אומר false, 0, null, undefined או מחרוזת ריקה), תן את האיבר השני, כך הגדרת הפונקציה קורית רק פעם אחת למרות שבפועל כל הקוד שב-expression רץ. אחרי הפעם הראשונה מה שקורה אחרי ה-|| לא מתבצע כי x כבר לא שווה ערך ל-false.
this.runtimeStyle.behavior="none";
קוד זה הוא בעצם ה"תרופה" ל-css expression. הוא יקרה רק פעם אחת לאלמנט ומייד ייעלם.
sizingMethod=el.currentStyle.backgroundRepeat=="no-repeat" ? "crop" : "scale";
טוב, אז אין באמת תמיכה ב-repeat של background, לשם כך היינו צריכים ליצור מספר אלמנטים ולמקם אבסולוטית תוך כדי חישוב המיקומים ליצירת גריד של תמונה אחת משוכפלת. ההיגיון מאחורי השורה – תמונות עם repeat תימתחנה. זה נועד ספציפית לתמונות רקע שאמורות לחזור על עצמן כמו בורדרים של אלמנט שצריכים להתרחב בהתאם לתוכן שלו.
var that=this;
this.attachEvent("onpropertychange",function (e) {
if (e.propertyName=="src") window.__fixPng(that);
});
קוד זה בא לענות על צורך של שינוי דינמי של src של תמונה. השימוש ב-onpropertychange נורה כאשר כל מאפיין שונה. בעזרת propertyName נבדוק האם שונה המאפיין src. אירוע זה עובד רק על IE.
מאחר וכל פונקציה מקבלת this משלה, ו-this שבתוך attachEvent הוא אינו האלמנט אלא החלון (למה?!), נאלץ לשמור אותו ברפרנס בשם that.
לבסוף, את הקוד נכליל בעזרת conditional comment ל-IE6 ומטה:
<!--[if lte IE 6]> <link rel="stylesheet" href="fixpng.css" type="text/css"/> <![endif]-->
מקווה שתמצאו קוד זה שימושי, אם כי לא לזמן רב מדי. אני מייחל מוות מהיר לשימוש ב-IE6
2 תגובות
כתיבת תגובה
עזר חקלית
כיוון שבאמת ירד הרקע המעצבן שיש על הקע השקוף
אבל בפינת התמונה בצד שמאל למעלה מופע ריבוע עם X כאילו שאמורהלהופיע איזה תמונה שלא קיימת
אשמח לעזרה
תיצור תמונה ריקה שקופה בשם transparent.gif בתיקייה הראשית וזה יסדר את העיניין
כתיבת תגובה
תגיות מותרות לשימוש בתוכן
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre>