Share vì hữu ích

Tính năng scroll trong trang khi nhấp chuột vào button hay liên kết là rất phổ biến ở nhiều website. Hãy cùng Code Tốt nghiên cứu cách thực hiện bằng Javascript ES6 nhé.

Tính năng scroll trong trang

Scroll trong trang là tính năng khi trong cùng một trang có nội dung dài, thường áp dụng cho các trang landing hoặc các trang có nhiều lớp nội dung. Khi người dùng nhấp chuột vào button hoặc liên kết, màn hình sẽ scroll xuống phần phía dưới tương ứng.

Tất nhiên, trong trình duyệt vẫn sẽ hỗ trợ, nhưng khi làm với Javascript, bạn phải đảm bảo nó hoạt động kèm animation.

Các bước thực hiện scroll trong trang bằng Javascript ES6

Tạo anchor trong markup

Đầu tiên, bạn cần gán anchor cho khu vực sẽ scroll đến:

<a id="intro" class="section__anchor"></a>
<section class="section intro"></section>

Tạo trigger trong markup

Tiếp đến, bạn gán href link cho button hoặc liên kết mà người dùng sẽ nhấp chuột vào.

<a href="#intro" class="button js-scroll">Read More</a>

Nếu bạn muốn nhấp chuột vào tất cả liên kết bất kì dạng #something thì bạn có thể bỏ qua gán class prefix Javascript js-scroll. Tất nhiên, ta cũng sẽ cần thay đổi code một chút trong Javascript.

Sử dụng thư viện animation Javascript Tweet.js

Để làm hoạt động mượt mà, bạn cần sử dụng thư viện Tweezer.js, hỗ trợ với ES6 hay cả ES5. Bạn có thể cài đặt với npm install --save-dev Tweezer.js

Các function sử dụng

Sau đó, ta lần lượt xây dựng các function có liên quan (để viết theo kiểu functional programming):

Function có liên quan

Đây là các function nhỏ lẻ có liên quan, giúp ta thực hiện một công việc duy nhất nào đó.

Function sau sẽ làm nhiệm vụ bắt điểm scroll đầu tiên

const getScrollTop = (el = document.documentElement) => el === document.documentElement ? (window.pageYOffset || el.scrollTop) : el.scrollTop

Function sau sẽ làm nhiệm vụ check xem đường dẫn (href) có chứa kí tự đầu tiên là “#” không:

const isHash = href => href[0] === '#'

Function làm nhiệm vụ lấy value của href:

const getHref = link => link.getAttribute('href')

Function để ta set giá trị cho một object

const setProp = (prop, value, obj) => {
  obj[ prop ] = value
  return obj
}

Function chính

Hai function sau sẽ làm nhiệm vụ chính để tìm và scroll đến target:

const scrollDown = href => {
 const targetHref = document.querySelector(href)
 if (targetHref) { 
   const offset = targetHref.getBoundingClientRect().top + getScrollTop()
   if (offset) {
     scrollTop(offset, undefined)
   }
 }
 return targetHref
}
const scrollTop = (offset, callback, el) => {
  // Tweezer.js requires both of start and end points
  new Tweezer({
    start: getScrollTop(el),
    end: offset
  })
   .on('tick', (v) => {
     (typeof el === 'undefined')
       ? window.scrollTo(0, v)
       : setProp('scrollTop', v, el)
   })
   .on('done', () => {
     if (typeof callback !== 'undefined') {
       callback()
     }
   })
 .begin()
}

Gán event listener vào trigger:

const el = document.querySelector('[data-module="anchor"]')
if (el) {
 // Or targets = document.querySelectorAll('.js-scroll')
 const targets = Array.prototype.slice.call(el.querySelectorAll('a'))
 targets.forEach(target => {
   target.addEventListener('click', (e) => {
     const el = getHref(target)
     if( isHash(el) ) {
       e.preventDefault()
       scrollDown(el)
     }
   })
 })
}

Kết luận

Code Tốt không cung cấp tài liệu hoàn chỉnh cho các bạn. Các bạn phải tự tay làm, thử nghiệm và kiểm tra mức độ chính xác của các function nhé.

Share vì hữu ích

Tác giả: Khôi 'Pro' Nguyễn

Technical Lead tại Solis Lab. Quản lý ngôn ngữ tại vi.wordpress.org.

Trả lời