عضویت در خبرنامه

با عضویت در خبرنامه از آخرین مقالات اطلس ساختار داده باخبر شوید

عضویت
arrow_backward بازگشت

انتقال صفحه به صورت پیوسته (Page Transition) در وب سایت (قسمت اول )

مقدمه

هرگاه ارتباط کاربر با وب سایت دچار وقفه شود ، احتمال خروج از وب سایت افزایش می یابد.انتقال از یک صفحه به صفحه دیگر در وب سایت در صورتی که لحظاتی باعث ایجاد یک صفحه خالی شود و یا مدت زمان زیادی طول بکشد تا صفحه جدید بارگذاری شود این وقفه را بوجود می آورد.انتقال صفحه پیوسته (Page Transition) بین صفحات وب سایت می تواند با ایجاد پیوستگی بصری میان مطالب وب سایت تجربه کاربر از وب سایت را مطلوب تر کند و نتایج نامطلوب وقفه بین مطالب وب سایت را حذف کند که در نهایت منجر به بازخورد مثبت تر کاربران می شود . در عین حال از لحاظ زیبایی ، Page Transition در صورت اجراء مطلوب ، حس و حال دوست داشتنی به وب سایت خواهد داد .

در این مقاله ، سعی می کنم Page Transition را بصورت قدم به قدم و با مثال برای شما شرح بدهم .همینطور در مورد مزایا و معایب این تکنیک هم صحبت خواهم کرد .

 

نمونه ها

بسیاری از اپ های موبایل به خوبی از این تکنیک استفاده می کنند . در مثال زیر می بینیم که انیمیشن چگونه از انتقال سلسله مراتبی و ارتباط فضایی میان صفحات استفاده می کند .

چرا ما از این تکنیک فوق العاده برای وب سایتمان استفاده نکنیم ؟ چرا باید این حس را به کاربرانمان منتقل کنیم که با هر کلیک ، به صفحه مقصد تله پورت می شوند ؟!!!!

 

نحوه ایجاد Transition میان صفحات



از طریق فریم ورک ها

قبل از اینکه آستین ها را بالا بزنید ، بهتر است توضیحی در مورد امکان انجام Page Transition از طریق فریم ورک ها بدهم . اگر از فریم ورک هایی مانند AngularJS ، Backbone.js یا Ember استفاده می کنید ، ایجاد Page Transition بسیار ساده تر خواهد بود چون سازندگان این فریم ورک ها از قبل کدهای جاوا اسکریپت مربوطه را برایتان نوشته اند . برای درک بهتر Page Transition کافیست به دستورالعمل ها و مستندات (Documents) این فریم ورک ها مراجعه کنید ، چون احتمالا آنجا توضیحات و مثال های خوبی پیدا خواهید کرد.

 

راه اشتباه

اولین فکری که برای ایجاد Transition میان صفحات به ذهنم رسید چیزی شبیه به ایجاد کد زیر بود :

 

document.addEventListener('DOMContentLoaded', function()
 {
  // Animate in
});
 
document.addEventListener('beforeunload', function()
 {
  // Animate out
});

اصول کار ساده است ؛ وقتی صفحه کاربر صفحه را ترک می کند یک انیمیشن اجرا می شود ، و وقتی صفحه جدید بالا می آید یک انیمیشن دیگر اجرا می شود .

اما بزودی فهمیدم این راه حل نقاط ضعفی دارد :

ما نمی دانیم که بارگذاری صفحه جدید چقدر زمان می برد ، بنابراین انیمیشن پیوسته نخواهد بود .
نمی توانیم انتقالی ایجاد کنیم که محتوای قبلی و جدید را به هم پیوند بزند .
در حقیقت تنها راه دست یابی به انتقالی پیوسته و ملموس کنترل داشتن بر روی پروسه تغییر صفحه است . بنابراین بهتر است راه های دیگری را امتحان کنیم .

 

راه صحیح

بیایید با هم مراحل ایجاد یک انتقال صفحه پیوسته را بررسی کنیم . Page Transition بر پایه تکنیکpushState AJAX ( or PJAX ) navigation ایجاد می شود ، که وب سایت ما را دقیقا به یک وب سایت تک صفحه ای تبدیل می کند که در آن ، پیمایش میان قسمت های مختلف ، نیازی به وقفه ندارد .

البته این ، تنها تکنیک بکار رفته در Page Transition نیست ، بلکه ما از ترکیبی از تکنیک های دیگر نیز برای خلق این پدیده استفاده خواهیم کرد . در ادامه تک تک این تکنیک ها را شرح خواهیم داد .

 

تغییر رفتار پیش فرض هنگام کلیک بر روی لینک

اولین قدم ما ایجاد یک event listener برای click event های تمام صفحه است که بتواند رفتار پیش فرض مرورگر هنگام کلیک بر روی یک لینک را تغییر داده و آن را به رفتار دلخواه ما تبدیل کند .

// Note, we are purposely binding our listener on the document object
// so that we can intercept any anchors added in future.
document.addEventListener('click', function(e) {
  var el = e.target;

  // Go up in the nodelist until we find a node with .href (HTMLAnchorElement)
  while (el && !el.href) {
    el = el.parentNode;
  }

  if (el) {
    e.preventDefault();
    return;
  }
});

این روش اضافه کردن یک event listener به المان پدر ، به جای اضافه کردن آن به هر node جداگانه ، event delegation خوانده می شود و به سبب طبیعت event-bubbling رابط برنامه نویسی کاربردی HTML DOM قابل پیاده سازی است .

 

Fetch کردن صفحه مقصد

حالا که توانستیم رفتار مرورگر را هنگام تغییر صفحه عوض کنیم ، می توان با استفاده از Fetch API بصورت دستی صفحه مقصد را fetch کنیم . نگاهی به تابع زیر بیاندازید که با آن می توان محتویات HTML یک صفحه با URL مشخص را fetch کرد .

function loadPage(url) {
  return fetch(url, {
    method: 'GET'
  }).then(function(response) {
    return response.text();
  });
}

برای مرورگرهایی که از Fetch API پشتیبانی نمی کنند ، می توان از Polyfill و یا روش قدیمی و خوب XMLHttpRequest استفاده کرد .

 

تغییر URL کنونی

HTML 5 دارای یک API فوق العاده به نام pushState است ، که به وب سایت قابلیت دسترسی و دستکاری history مرورگر را بدون بارگذاری صفحه جدید می دهد . در کد پایین ما از این API برای تغییر URL فعلی به URL صفحه مقصد استفاده می کنیم . دقت کنید که این تکه کد ، همان کد قسمت اول است که یک pushState به آن اضافه شده .

if (el) {
  e.preventDefault();
  history.pushState(null, null, el.href);
  changePage();

  return;
}

اگر دقت کرده باشید ، ما یک تابع در هم در این تکه کد به نام changePage صدا کردیم ، در مورد این تابع بعدا توضیح خواهم داد . همین تابع در هنگام رخ دادن popstate event هم صدا می شود ( این event زمانی فعال می شود که در history مرورگر تغییری ایجاد شود ؛ مانند زمانی که کاربر بر روی دکمه back مرورگر کلیک کند .) :

window.addEventListener('popstate', changePage);

 

در مجموع تا اینجا توانستیم یک سیستم ناوبری خیلی ابتدایی ایجاد کنیم که دارای دو گزینه فعال و غیرفعال است .

حالت فعال این سیستم زمانی اتفاق می افتد که کاربر بر روی یک لینک کلیک می کند و ما با pushState مقدار URL فعلی را عوض می کنیم ولی حالت غیرفعال مربوط به زمانی است که URL عوض می شود و ما از طریق popstate event از آن مطلع می شویم . در هر دو حالت تابع changePage را صدا می کنیم که باعث خواندن صفحه مقصد شده و آن را بارگذاری می کند .

 

دریافت (Parse) و بارگذاری محتوای جدید

معمولا صفحات پیمایش شده المان های مشترکی دارند مانند header یا footer . فرض کنید ما از ساختار DOM زیر برای تمامی صفحات وب سایت استفاده کنیم :

<header>
 … 
</header>

 <main>
    <div class="cc">
      … 
    </div>
 </main>

<footer>
 … 
</footer>

در این حالت تنها قسمتی که در هر صفحه جدید باید عوض شود محتویات ظرف cc است . بنابراین تابع changePage ما چیزی مانند کد زیر خواهد بود :

 

var main = document.querySelector('main');

function changePage() {
  // Note, the URL has already been changed
  var url = window.location.href;

  loadPage(url).then(function(responseText) {
    var wrapper = document.createElement('div');
        wrapper.innerHTML = responseText;

    var oldContent = document.querySelector('.cc');
    var newContent = wrapper.querySelector('.cc');

    main.appendChild(newContent);
    animate(oldContent, newContent);
  });
}

 

انیمیشن

هنگامی که کاربر بر روی یک لینک کلیک می کند ، تابع changePage صفحه مقصد را fetch می کند ، سپس ظرف cc را استخراج می کند و آن را به المان mainاضافه می کند . در این مرحله ما دو تا ظرف cc داریم ، اولی مربوط به صفحه قدیمی و دومی مربوط به صفحه جدید است .

تابع بعدی ، animate ، به تبدیل پیوسته ظرف اول به ظرف دوم می پردازد ، اولی را محو (fade out) کرده و در همین زمان ظرف دوم را آشکار (fade in) می کند که جایگزین ظرف قدیمی شود .در این مثال من برای ایجاد انیمیشن از Web Animation API استفاده کردم ، طبیعیه که شما آزادید از هر تکنیک یا کتابخانه ای که دلتان می خواهد برای این کار استفاده کنید .

function animate(oldContent, newContent) {
  oldContent.style.position = 'absolute';

  var fadeOut = oldContent.animate({
    opacity: [1, 0]
  }, 1000);

  var fadeIn = newContent.animate({
    opacity: [0, 1]
  }, 1000);

  fadeIn.onfinish = function() {
    oldContent.parentNode.removeChild(oldContent);
  };
}

کد نهایی را می توانید از این لینک در GitHub دریافت کنید .

مطالب گفته شده ، پایه و اساس انتقال پیوسته میان صفحات یک وب سایت است .

در قسمت دوم این مقاله به بررسی هشدارها و محدودیت های این تکنیک و همچنین توسعه هرچه بیشتر آن خواهیم پرداخت .

با ما همراه باشد .