چند وقت پیش مجتبی تو بلاگ قبلیش، مطلبی نوشته بود با این توضیح:
“همان طور که ممکن است تو بعضی از سایتها دیده باشید، در قسمت Navigation سایت، Themeهای مختلفی وجود دارد که کاربر می تواند یکی از آنها را انتخاب کرده و به آن محیط Switch کند. برای انجام این کار، چندین راه وجود دارد:
- درست کردن دو نوع صفحه وب با طرح های مختلف
- استفاده از یک صفحه وب و ۲ Style Sheet”
و در ادامه مقاله روش دوم را توضیح داده بود
همونطور که نوید تو کامنتای اون مقاله نوشته: “عیب این روش اینه که اگه بازدید کننده وارد یه صفحه دیگه بشه اون استایل انتخابی از بین میره بعدم اینکه برای دفعه بعدی که بازدیدککنده به سایت اومد اون تنظیم نمیمونه”. قرار بود خودش تو سایتش روشیو بنویسه که این مشکلو نداشته باشه ولی هرچی ما صبر کردیم خبری نشد که نشد!!
اول فقط میخواستم خیلی کلی روش انجام این کارو بنویسم ولی وقتی بهاین مقاله برخوردم دیدم بهتره یه سری توضیحات دیگه هم اضافه کنم.
به هر حال این نوشته ترجمه کامل اون مقاله نیست و بعضی جاها چیرهایی بهش اضافه کردم و بعضی جاها نوشتههایی از اون کم شده. اگر به ایرادی تو این نوشته برخوردین بهم اطلاع بدین!!
اگه حوصله اضافی ندارین یا یه کاربر معمولی هستین فقط تیترهای چگونگی استفاده از استایل شیتها و حالا همه اینا که چی؟ رو بخونید.
چگونگی استفاده از استایل شیتها
مرورگرها از روی استیلهای تعریف شده توسط استایل شیتها به فرمت دهی و نمایش اطلاعات درون صفحه اچتمل میپردازند. تعریف و استفاده از استایل ها در صفحات اچتمل به سه روش مختلف ممکن میباشد.
۱)استایلشیتهای خارجی (external style sheet)
در این روش تمامی استایلها و تعاریف نمایشی درون فایلی جداگانه قرار گرفته و بسیار مناسب حالتهائی است که قرار است که استایلی به بیش از یک صفحه اچتمل اعمال شود. در این روش ما یک فایل با پسوند .CSS را به صفحه لینک میکنیم.
<link rel="stylesheet" type="text/css" href="mystyles.css>
۲)استایلشیتهای داخلی (Internal Style Sheet)
کاربرد این روش در حالتهائی است که صفحه اچتمل نیازمند تعریف استایلی منحصر به فرد و مجزا بوده و استایل طراحی شده فقط بدرد آن صفحه خواهد خورد. در این حالت باید کدهای حاوی تعریف استایل درون تگهای <style> و <style/> قرار گرفته و معمولا نتیجه درون بخش head صفحه اچتمل گذاشته میشود.
<style type="text/css>
h2 {
color: red;
}
body {
background-color: red;
}
p.text {
margin-left: 20px;
}
</style>
۳)استایلشیتهای درجا (Inline Styles)
کاربرد این روش در مواردی است که باید برای یک المان (یا گروهی) خاص استایلی اعمال شود. در این حالت باید از شناسهای به نام style که تقریبا در تمامی تگها قابل اعمال است استفاده شود.
<p style="color: red; margin-left: 20px;">This is a paragraph</p>
توضیحات بیشتر و کاملتر اینجا.
برای اینکه بتوانیم بین ستایل شیتها Swithch کنیم باید از ستایل شیتهای خارجی استفاده کنیم.
ستایل شیتهای خارجی را می توان به سه نوع مختلف تعریف کرد:
۱. Persistent
این ستایلشیتها همیشه فعال هستند و میتوانند با ستایلشیتهای فعال دیگر ترکیب شوند و به عنوان ستایلشیتهای کلی و عمومی استفاده میشوند (ستایلشیتهایی که در حالات معمولی تعریف میکنیم از این گونهاند).
برای تعریف ستایلشیتهای از نوع Persistent، شناسه rel مقدار “stylesheet” میگیرد و احتیاجی به شناسه title نیست.
<link rel="stylesheet"
type="text/css" href="styles.css" />
۲. Preferred
این ستایلشیتها در حالت پیش فرض فعال هستند (هنگام لود شدن صفحه مورد استفاده قرار میگیرند) و هنگامی که کاربر یک ستایل alternate را انتخاب کند غیر فعال میشوند (در حالتی که صفحه چند ستایل شیت مختلف دارد در ابتدا این نوع ستایل شیت مورد استفاده فرار میگیرد مگر اینکه بوسیله کوکیها این روال تغییر کند).
برای تعریف ستایلشیتهای از نوع Preferred، شناسه rel مقدار “stylesheet” را میگیرد و ستایلشیت بوسیله شناسه title نامگذاری میشود.
چندین استایل شیت نوع preferred را میتوانیم با دادن title یکسان در یک گروه قرار دهیم. در این صورت تمام ستایلشیتهای در یک گروه با هم فعال یا غیر فعال میشوند.
<link rel="stylesheet"
type="text/css" href="styles.css"
title="standard" />
۳. Alternate
این ستایلشیتها میتوانند توسط کاربر به عنوان alternatives (ثانوی) یا preferred (دلخواه) انتخاب شوند که به کاربر اجازه میدهد سایت را به طور دلخواه خود ببیند.برای تعریف ستایلشیتهای از نوع Alternate، شناسه rel مقدار “alternate stylesheet” میگیرد و ستایل شیت بوسیله شناسه title نامگذاری میشود. همانند ستایلشیتهای نوع Preferred، این ستایل شیتها با داشتن title یکسان در یک گروه قرار میگیرند.
<link rel="alternate stylesheet"
type="text/css" href="styles.css"
title="style2" />
نکته مهم: این روابط و تعاریف فقط در مورد ستایل شیتهای خارجی که به صفحه لینک میشوند صادق است!
عوض کردن ستایل شیتها
وقتی یک صفحه برای بار اول لود میشود، ستایل شیتهای نوع Persistent و Preferred برای صفحه کاربرد دارند و ستایل شیتهای Alternate بعدا میتوانند توسط کاربر انتخاب شوند. W3C به ما میگوید که مرورگر باید حق انتخاب ستایل شیتی که دوست داریم استفاه کنیم را توسط یک drop-down menu یا tool bar به ما بدهد. یعنی ما چندین ستایل شیت داریم و بازدیدکننده میتواند ستایل مورد علاقه خود را توسط یک منو انتخاب کند.
ولی اینجا ما به مشکلی بر میخوریم .. یک مشکل بزرگ! Mozilla یک منو در نظر گرفته که توسط آن میتوان ستایل شیتها را تغییر داد ولی در Microsoft Internet Explorer ما چنین امکانی را نداریم. یعنی ما چندین ستایل شیت داریم ولی راهی برای دسترسی به آنها نداریم!!
به هر حال میتوان به استفاده از جاواسکریپت به همراه DOM این مشکل را حل کرد که توسط آن در اینترنت اکسپلور بتوانیم ستایل شیت مورد نظرمان را انتخاب کنیم. همچنین میتوانیم ستایل شیت انتخابی را در یک کوکی ذخیره کنیم. و از آنجایی که از تگهای لینک W3C استفاده میکنیم، اسکریپت ما تداخلی با منوی مرورگر Mozilla پیدا نمیکند. (در واقع اولویت آنرا تنزل میدهد!)
اسکریپت
در ایتدا به اسکریپتی نیاز داریم که بتواند سه نوع مختلف ستایل شتها را از هم تمییز دهد. این کار نسبتا ساده است، فقط کافی است دوتا از شناسههای المان لینک را چک کنیم.
۱. آیا این یک لینک به یک ستایل شیت است؟
HTMLLinkElement.getAttribute("rel").indexOf("style") != -1
۲. آیا شناسه title وجود دارد؟
HTMLListElement.getAttribute("title")
۳. آیا شناسه rel دارای مقدار “alternate” است؟
HTMLLinkElement.getAttribute("rel").indexOf("alt") != -1
توجه داسته باشید که مقدار “alt” را چک میکنیم چون بعضی از مرورگرها مقدار “alternate” را به جای “alternative” قبول میکنند.
با استفاده از این سه آزمون میتوانیم تابعی بنویسیم تا بین ستایل شیتها Switch کنیم. به این ترتیب با استفاده از یک حلقه بین تمام المانهای لینک در صفحه حرکت میکنیم و تمام ستایل شیتهای preferred و alternate را که نمیخواهیم، غیرفعال و آنهایی که میخواهیم، را فعال میکنیم!
توجه شود که فقط ستایل شیتهای preferred و alternate دارای شناسه title هستند در نتیجه فقط این نوع ستایل شیتها را میتوان فعال یا غیرفعال کرد.این تابع چیزی شبیه این است:
function setActiveStyleSheet(title) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
}
یک شناسه disabled در DOM Level 2 برای w3c مشخص شده است که مقدار false را برای ستایل شیتهایی که در صفحه استفاده شده است به خود میگیرد. این شناسه در مرورگر Mozilla کاربد دارد اما متاسفانه در MSIE نه!
MSIE داری یک شناسه وابسته به HTML است که آنهم disabled خوانده میشود اما در اینجا مقدار false را برای تمام لینکهایی که در صفحه وجود دارد به خود میگیرد.
برای اینکه کاربرد شناسه disabled در MSIE با کاربرد آن در DOM Level 2 یکی شود تابع setActiveStyleSheet را فراخوانی میکنیم.
کوکیها
حالا بازدید کننده میتواند ستایل شیتها را مطابق میل خودش تغییر بدهد این خوب است اما الان فقط همان صفحه مطابق میل بازدید کننده است نه کل سایت. یعنی اگر بازدیدکننده به صفحه دیگری از سایت برود یا سایت را ترک کند ستایل شیت انتخابی او هم از بین می رود و در مراجعه بعدی سایت با ستایل شیت نوع Preferred مشاهده میشود. این مشکل را میتوان با استفاده از کوکیها مرتفع کرد.
ما نیاز به یک تابع داریم تا ستایل شیت مورد نظر را از درون کوکی برگرداند همچنین به دو تابع برای ذخیره و خواندن کوکی نیاز داریم.
برای گرفتن ستایل شیت مورد نظر از کوکی دنبال یک ستایل شیت preferred یا alternate با title مورد نظر میرویم.
ابتدا تمام المانهای لینک درون صفحه را برسی میکنیم (با ایجاد یک حلقه برای برسی همه) که آیا لینک به یک ستایل شیت است یا نه. اگر بود، برسی میکنیم که ستایل شیت دارای شناسه title هست یا نه. این به ما نشان میدهد که ستایل شیت از نوع preferred یا alternative است. سپس برسی میکنیم که ستایل شیت فعال است یا خیر. اگر همه برسیها مقدار true داشت یعنی ستایل شیت صحیح را پیدا کردیم و تابع، title آنرا به عنوان ستایل شیتی که باید مورد استفاده قرار گیرد بر میگرداند.
function getActiveStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("title")
&& !a.disabled) return a.getAttribute("title");
}
return null;
}
چون این مقاله درمورد ستایل شیتها است و کوکیها یک موضوع کاملا جدا محسوب میشود قصد ندارم اینجا در مورد توابع کوکیها صحبت کنم و فقط آنها را اینجا بازنویسی میکنم تا در آینده در مورد کوکیها به طور مفصل صحبت کنم.
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
برای استفاده از این کوکیها باید از ادارهکنندگان رویداد (event listener)!! از نوع onload و onunload استفاده کنیم.
onLoad
اداره کننده رویداد onLoad هنگامی که صفحه در حال لود شدن است اجرا میشود (در اینجا برای پیدا کردن ستایل شیت انتخابی کاربر از آن استفاده میکنیم).
برای اینکه بفهمیم کدام ستایل شیت، ستایل شیت انتخابی است، به تابع دیگری احتیاج داریم. چون این تابع بسیار شبیه به تابع getActiveStyleSheet کار میکند، توضیحی در مورد اینکه چگونه کار میکند نمیدهیم ولی چیزی شبیه این خواهد بود:
function getPreferredStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("rel").indexOf("alt") == -1
&& a.getAttribute("title")
) return a.getAttribute("title");
}
return null;
}
در تایع onload ایتدا ما title را به صورت یک متغیر تعریف میکنیم که مقدار ستایل شیت قبلی که در کوکی ذخیره شده است را نیز همراه خود دارد یا اگر این مقدار وجود نداشته باشد، title ستایل شیت نوع preferred را همراه خود دارد (برای اینکه همه چیز منطقی به نظر برسد، نام کوکی را style قرار میدهیم!).
سپس باید تابع setActiveStyleSheet را فراخوانی کنیم تا مقدار متغیر title را تصویب کند!!
window.onload = function(e) {
var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);
}
توجه کنید که شاید بخواهیم این تابع را قبل از رویداد onload فراخوانی کنیم که این امر باعث میشود صفحه بدون ستایل شیت انتخابی نماش داده شود.
همچنین توجه کنید که شاید هنگام لود شدن صفحه شما ابتدا سایت را با ستایل شیت نوع Preferred ببینید ولی با تمام شدن کار لود صفحه ستایل شیت مورد نظر شما (اگر غیر از Preferred style sheet باشد) نمایان میشود. (چرا؟)
onUnload
ذخیره کوکی هنگام یک رویداد onUnload بسیار سادهتر است. تنها کاری که باید انجام بدهیم استفاده از تایع getActiveStyleSheet برای برگرداندن ستایل شیت فعال و ذخیره آن در یک کوکی است.
window.onunload = function(e) {
var title = getActiveStyleSheet();
createCookie("style", title, 365);
}
توجه کنید که این عمل هنگامی که بازدیدکننده در حال ترک صفحه است صورت میگیرد در نتیجه اگر در هنگام بازدید از یک سایت، صفحه جدیدی از سایت را باز کنیم (بدون ترک صفحه قبلی) شاید ستایل شیت انتخابی ما در صفحه جدید نباشد (چرا؟)
حالا همه اینا که چی؟
اگه یه کاربر معمولی هستید یا اصلا حوصله خوندن نوشتههای بالا را ندارید فقط لازم است این کارها را انجام دهید:
۱. فایل styleswitcher.js را دانلود کنید (این فایل حاوی تمام توابعی است که به آنها نیاز دارید) و آنرا به تمام صفحاتی از سایت که میخواهید عمل Style Sheet Switch در آن صورت پذیرد اضافه کنید:
<script type="text/javascript"
src="/scripts/styleswitcher.js"></script>
۲. لینک کردن ستایل شیتها:
-> اگر ستایل شیتهایی وجود دارد که میخواهید در هر صورت فعال باشند، آنرا به صورت Persistent Style Sheet به صفحه لینک کنید. توجه کنید که این ستایل شیتها در هر حال فعال و مقدار آنها معتبر خواهد بود حتی در صورت استفاده از ستایل شیتهای نوع preferred و یا alternate. مگر اینکه آن مقدار در یکی از ستایل شیتهای انتخابی تغییر کند.
-> ستایل شیتی که میخواهید در حالت پیش فرض در صفحه لود شود را به صورت preferred Style Sheet به صفحه اینک کنید. توجه شود مقدار شناسه title که در اینجا مورد استفاده قرار میگیرد، هنگام فراخوانی تابع setActiveStyleSheet مورد نیاز است.
<link rel="stylesheet"
type="text/css" href="style1.css"
title="default" />
توجه کنید که حتی در صورتی که ستایل شیت انتخابی شما چیز دیگری باشد، در هنگام لود شدن صفحه ابتدا شما این ستایل، و با اتمام لود شدن صفحه ستایل انتخابی را مشاهده خواهید کرد. (چرا؟)
در صورتی که شما هیچ preferred Style Sheet تعریف نکنید، اولین ستایل شیت نوع Alternate تعریف شده جای آنرا میگیرد.
-> ستایل شیتهایی که میخواهید بعدا توسط کاربران قابل انتخاب باشند را از نوع Alternate Style Sheet تعریف کنید.
<link rel="alternate stylesheet"
type="text/css" href="style2.css"
title="style two" />
حالا باید به بازدیدکنندگان امکان انتخاب ستایل شیت مورد علاقهشان را بدهیم. برای این کار از رویداد onClick در جاوا اسکریپت و المان لینک در HTML استفاده میکنیم:
<a href="#"
onclick="setActiveStyleSheet('default');
return false;">change style to style one</a>
<a href="#"
onclick="setActiveStyleSheet('style two');
return false;">change style to style two</a>
هنگام ترک هر صفحه، آخرین Theme از سایت را که مشاهده شده در کوکی ذخیره میشود. پس همانطور که در بالاتر گفته شد، این عمل هنگامی که بازدید کننده در حال ترک صفحه است صورت میگیرد در نتیجه اگر در هنگام بازدید از یک سایت، صفحه جدیدی از سایت را باز کند (بدون ترک صفحه قبلی) شاید ستایل شیت انتخابی او در صفحه جدید نباشد (چرا؟)
نکته مهم و پایانی هم اینکه همه لینکهای به ستایل شیتها و فایل جاوا اسکریپت باید به همه صفحات سایت اضافه شود و اگر ستایل شیتهایی وجود دارند که میخواهید با هم فعال و غیرفعال شوند، به شناسهtitle آنها مقدار مشابه دهید.
این مفاله شاید در آینده دچار تغییراتی شود در ضمن به پنج نفر از کسانی که به چند چرای پرسیده شده در این مقاله جواب صحیح بدهند به قید قرعه یک عدد پژو ۲۰۶ نشان داده خواهد شد (:.
لینک مطلب در وبلاگ یک نعلبکی پر از راز