Hi 🤓 Cảm ơn bạn đã ghé thăm blog này, nếu những bài viết trên blog giúp ích cho bạn. Bạn có thể giúp blog hiển thị quảng cáo bằng cách tạm ngừng ad blocker 😫 và để giúp blog duy trì hoạt động nếu bạn muốn.
Cảm ơn bạn!

Đây là một dạng slide cơ bản, lí do mình viết bài này là để giúp các bạn hiểu về cách làm slide bằng javascript. Thay vì lao vào ngay các thư viện tại sao ta không thử tìm hiểu qua cách hoạt động của Slide đúng không 😁😁.

Để bắt đầu thì trước tiên mình sẽ tạo HTML nhé:

<div class="review">
  <div class="header-content">
    <div class="title">
      <h2>Slideshow With Vanilla JavaScript</h2>
    </div>
    <div class="nav">
      <i class="fas btn fa-chevron-left btnLeft"></i
        ><i class="fas btn fa-chevron-right btnRight"></i>
    </div>
  </div>
  <div class="review-box">
    <div class="box">
      <div class="image">
        <img
             src="https://images.unsplash.com/photo-1596050843849-db303b16b50e?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80"
             alt=""
             />
      </div>
      <div class="name">Simon</div>
      <div class="designation">Student</div>
      <div class="text">
        Lorem ipsum dolor sit amet, consectetur adipisicing
        elit, sed do eiusmod tempor incididunt ut labore et
        dolore magna aliqua. Ut enim ad minim veniam.
      </div>
    </div>
    <!-- end box -->
    ...
  </div>
</div>

Ở đoạn HTML mình tạo 1 div nav dùng để chứa button left và right. Thêm các hình vào div review-box. Ở đây mình sẽ cho 1 vài hình để tượng trưng.

phần css cũng khá đơn giản. Mình sẽ show các phần chính 😁😁 còn lại các bạn style theo ý mình nhé. Source mình để ở đầu bài viết nhé.

.review-box {
    display: flex;
    /* overflow: hidden; */
    transition: transform 0.3s linear;
}

Lí do mình thêm transition vì mình sẽ sử dụng javascript add các hiệu ứng vào review-box ^^.

Tiếp theo ta sẽ tới javascript nhé. Mình sẽ giải thích từng đoạn code để các bạn hiểu.

👉 Đầu tiên chúng ta sẽ get các element cần thiết ra nhé.

const listBox = document.querySelectorAll('.box');
const wrapperBox = document.querySelector('.review-box');
const btnLeft = document.querySelector('.btnLeft');
const btnRight = document.querySelector('.btnRight');
const reviewDiv = document.querySelector('.review');

Bước tiếp theo ta sẽ cần phải tìm width của 1 box trong slide và set width cho parent div dựa theo width của box. Làm như vậy để các box của chúng ta nằm trên một hàng và để làm được dạng slide này. width của box ta phải cố định lại. Đó là lí do ta phải tìm width của box.

Mình sẽ tạo một function make_slide(amountSlideAppear){} với tham số là số lượng box muốn show ở màn hình. Như hình trên là 3 box.

Ta cùng đi tìm width cho parent và width của 1 box.

const widthItemAndMargin = reviewDiv.offsetWidth / amountSlideAppear;
let widthAllBox = widthItemAndMargin * listBox.length;

Ta sẽ tìm width 1 box bằng cách:

Mình sẽ lấy width cố định của một div parent. Ở đây mình sẽ lấy div reviewDiv, Sau đó đem chia cho số lượng box muốn show ra sẽ tìm được width 1 box.

slideBox

Ví dụ mình muốn có 3 box show ra như hình trên thì sẽ lấy reviewDiv / 3 = width 1 box.

Đối với việc tìm width cho div parent chứa slide thì công việc khá đơn giản. ta chỉ cần lấy số lượng box * width 1 box.

Ta sẽ set width cho div parent:

wrapperBox.style.width = `${widthAllBox}px`;

Thành công ở bước đầu tiên, tiếp theo mình sẽ tạo khoảng cách cho các box bằng cách set margin-right cho từng box.

👉 trong biến widthItemAndMargin đã bao gồm margin của box rồi. nếu muốn set ta chỉ việc dùng margin cho box và bỏ phần margin đi sẽ ra width thực sự của box.

listBox.forEach((element) => {
  element.style.marginRight = '20px';
  element.style.width = `${widthItemAndMargin - 20}px`;
});

Sau khi xử lí width ta sẽ tới phần button left và right.

Mình sẽ tạo một biến đếm count = 0 để tính toán vị trí của các box. Muốn các box chuyển động sang trái hoặc phải ta sẽ dùng thuộc tính translate để di chuyển div parent theo ý muốn.

Để set translate đúng, ta cần phải tính toán được khi nào đến box cuối thì ta sẽ cho slide về đầu box và ngược lại.

Ở đây mình sẽ tìm vị trí box cuối như sau.

let spacing = widthAllBox - amountSlideAppear * widthItemAndMargin;

Lấy chiều rộng của toàn bộ box trừ đi số lượng box muốn show. Ta sẽ tìm được vị trí box cuối xuất hiện.

Mình ví dụ:

Ta có 4 box.

chiều rộng 1 box 300px.

chiều rộng all box là 4*300 = 1200px

Trên màn hình mình muốn có 3 box xuất hiện. Và khi click vào button sẽ tiến hoặc lùi 1 box.

Như vậy ví trí box cuối xuất hiện sẽ là 1200px - 3*300 = 300px.

Mình biết sẽ khó hiểu nhưng các bạn hãy tưởng tượng và console.log vị trí từng box sẽ hiểu nha 😁.

Mọi chuyện đơn giản hơn khi ta tìm được vị trí box cuối xuất hiện.

Tiếp theo chỉ cần xử lí button left và right là xong rồi ^^

btnRight.addEventListener('click', function () {
  count += widthItemAndMargin;

  if (count > spacing) {
    count = 0;
  }
  wrapperBox.style.transform = `translateX(${-count}px)`;
});

Với mỗi click vô button right mình sẽ cho translate của parent lùi đi với độ lùi bằng width của một box. Khi lùi về bên trái thì box bên phải sẽ hiện ra.

Đặt điều kiện nếu như ta vượt quá vị trí box cuối xuất hiện ở bên phải ngoài cùng. thì sẽ set count = 0 tức trở về vị trí đầu slide.

Tương tự như vậy với button left:

btnLeft.addEventListener('click', function () {
  count -= widthItemAndMargin;

  if (count < 0) {
    count = spacing;
  }
  wrapperBox.style.transform = `translateX(${-count}px)`;
});

Tiếp theo ta sẽ đến phần responsive, phần này cũng đơn giản và ngắn gọn. Cùng tìm hiểu nhé.

window.addEventListener('resize', function () {
  if (window.innerWidth >= 1366) {
    make_slide(3);
  } else if (window.innerWidth >= 992) {
    make_slide(2);
  } else {
    make_slide(1);
  }
});

const media = [
  window.matchMedia('(min-width: 1366px)'),
  window.matchMedia('(min-width: 992px)'),
];

if (media[0].matches) {
  make_slide(3);
} else if (media[1].matches) {
  make_slide(2);
} else {
  make_slide(1);
}

Mình dùng resize event để biết khi màn hình giảm width hoặc tăng width, ta sẽ tìm được width 1 box và set số lượng slide muốn show.

Còn matchMedia sẽ thực thi khi màn hình là laptop or mobile,... tương ứng sẽ show ra màn hình số lượng box ta muốn.

Và đây là kết quả:

Đây là toàn bộ code phần javascript:

const listBox = document.querySelectorAll('.box');
const wrapperBox = document.querySelector('.review-box');
const btnLeft = document.querySelector('.btnLeft');
const btnRight = document.querySelector('.btnRight');
const reviewDiv = document.querySelector('.review');
document.addEventListener('DOMContentLoaded', function () {
    // responsive
    window.addEventListener('resize', function () {
        if (window.innerWidth >= 1366) {
            make_slide(3);
        } else if (window.innerWidth >= 992) {
            make_slide(2);
        } else {
            make_slide(1);
        }
    });

    const media = [
        window.matchMedia('(min-width: 1366px)'),
        window.matchMedia('(min-width: 992px)'),
    ];

    if (media[0].matches) {
        make_slide(3);
    } else if (media[1].matches) {
        make_slide(2);
    } else {
        make_slide(1);
    }
});

function make_slide(amountSlideAppear) {
    // set width and margin for item slide
    const widthItemAndMargin = reviewDiv.offsetWidth / amountSlideAppear;
    let widthAllBox = widthItemAndMargin * listBox.length;
    wrapperBox.style.width = `${widthAllBox}px`;

    listBox.forEach((element) => {
        element.style.marginRight = '20px';
        element.style.width = `${widthItemAndMargin - 20}px`;
    });

    // handle slide
    let count = 0;
    let spacing = widthAllBox - amountSlideAppear * widthItemAndMargin;
    btnRight.addEventListener('click', function () {
        count += widthItemAndMargin;

        if (count > spacing) {
            count = 0;
        }
        wrapperBox.style.transform = `translateX(${-count}px)`;
    });

    btnLeft.addEventListener('click', function () {
        count -= widthItemAndMargin;

        if (count < 0) {
            count = spacing;
        }
        wrapperBox.style.transform = `translateX(${-count}px)`;
    });
}

🔥👉 Như vậy là mình đã hướng dẫn cho các bạn xong cách làm 1 slide đơn giản và đẹp mắt rồi. Qua bài hướng dẫn này mình hi vọng các bạn sẽ hiểu cách hoạt động của kiểu slide này và sẽ sáng tạo ra được các kiểu slide đẹp mắt khác.

Happy coding 😁😁🔥

Những bài viết khác có thể bạn thích:

  1. Tạo slide nhanh chóng và đẹp mắt với jquery slick slider
  2. Làm Dropdown Menu dễ dàng bằng Javascript
  3. Làm Random Text Animated đơn giản bằng Javascript
  4. Cách làm Infinite Scroll sử dụng Vanilla JavaScript
  5. Hướng dẫn làm reaction buttons sử dụng JavaScript
Có thể bạn thích ⚡
homiedev
About Me

Hi, I'm @devnav. Một người thích chia sẻ kiến thức, đặc biệt là về Frontend 🚀. Trang web này được tạo ra nhằm giúp các bạn học Frontend hiệu quả hơn 🎉😄.

Chúc các bạn tìm được kiến thức hữu ích trong blog này 😁😁.