Tạo Slideshow Siêu Đơn Giản Với jQuery

Tạo Slideshow Siêu Đơn Giản Với jQuery

Bạn có muốn thử sức mình để tự làm một slide ảnh với jQuery? Trong bài này mình sẽ chia sẻ tới các bạn cách mình code một slideshow như thế nào. Từ bài viết này các bạn có thể tham khảo và sáng tạo thêm để có thể tạo ra cho bản thân những sản phẩm tuyệt vời nhé.

jquery là gì?

Đầu tiên, mình muốn giới thiệu một chút về jQuery. jQuery là thư viện được viết từ JavaScript, giúp xây dựng các chức năng bằng Javascript dễ dàng, nhanh và giàu tính năng hơn. jQuery được tích hợp nhiều module khác nhau. Từ module hiệu ứng cho đến module truy vấn selector. Và hôm nay mình sẽ sử dụng những module này để tạo slideshow với nhiều hiệu ứng đẹp, chuyên nghiệp. Now, Let's go!

Tổ chức thư mục

Step 1: Tạo Trang HTML và import jQuery

1.1 Tạo khung HTML

Trong file index.html, mình có đoạn code sau:

<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Slideshow</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div class="container">
        <img class="slide" src="img/picture1.png" alt="">
        <img class="slide" src="img/picture2.png" alt="">
        <img class="slide" src="img/picture3.png" alt="">
        <img class="slide" src="img/picture4.png" alt="" >
    </div>

    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <script src="script.js"></script>
</body>
</html>

Trong đoạn code trên mình import jQuery bằng CDN nhé. Các bạn có thể tìm thấy jQuery CDN tại đây.

1.2: Thêm các button

Mình sẽ thêm các button sau trong file index.html:

  • 2 button phải và trái
  • 4 button đánh số từ 1 đến 4
<img class="btn-change" id="next" src="icon/next.png" alt="">
<img class="btn-change" id="prev" src="icon/prev.png" alt="">

<div class="change-img">
    <button class="active">1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
</div>

Lưu ý: Bạn phải chỉnh sửa đường dẫn trong thuộc tính src cho phù hợp với cách tổ chức thư mục và tên ảnh.

Step 2: Tùy chỉnh bằng CSS

Oops! Trang web của chúng ta vẫn còn lộn xộn thế này. Giờ chúng ta cùng nhau code CSS để slide hiện lên nhé!

2.1 Xử lý hình ảnh:

  • Ẩn các hình ảnh số 2,3,4 bằng cách thêm thuộc tính display: none
  • Điều chỉnh kích thước hình ảnh về 710x400
img.slide {
    width: 710px;
    height: 400px;
}

img.slide:not(:first-child) {
    display: none;
}

Trong đoạn code trên mình có sử dụng selector :not(:first-child). Đây là sự kết hợp giữa 2 selector

  • :not(element) chọn các phần tử ngoại trừ element
  • :first-child chọn phần tử đầu tiên

Như vậy, bằng cách dùng :not(:first-child) mình có thể đặt cho tất cả các ảnh ngoại trừ bức đầu tiên thuộc tính display: none

2.2 Điều chỉnh container chứa ảnh (Kích thước, viền khung, vị trí)

.container {
    width: 710px;
    height: 460px;
    margin: 0 auto;
    border: 2px solid #ccc;
    position: relative;
    padding: 5px;
}

2.3 Điều chỉnh 2 button chuyển slide (Kích thước, vị trí)

.btn-change {
    width: 30px;
    height: 30px;
    position: absolute;
    top: 50%;
    transform: translateY(-100%);
}

#next {
    right: 10px;;
}

#prev {
    left: 10px;
}

2.4 Điều chỉnh 4 button số (Kích thước, màu sắc, vị trí, hiệu ứng di chuột)

.change-img {
    text-align: center;
    margin-top: 1rem;
}

button {
    background: rgb(0, 153, 255);
    width: 30px;
    height: 30px;
    border-radius: 50%;
    margin-right: 20px;
    font-weight: bold;
    border: none;
}

button.active {
    background: rgb(7, 101, 163);
    color: white;
}

Step 3: Xử lý JS

Mình đề xuất các bạn nên để toàn bộ code chính trong hàm:

$(document).ready(function() {
    //Your code
});

Mục đích là để đàm bảo document được render ra hết thì những script trong nó mới được thực thi. Tránh trường hợp khi các thành phần document chưa được render hết thì JS đã gọi (rất dễ gây ra lỗi hoặc không thực thi đúng theo ý muốn)

3.1 Xác định số chỉ vị trí cho ảnh đầu và ảnh cuối

Tại đây các bạn cần quay lại index.html và bổ sung thêm một thuộc tính cho các image trong slide. Mục đích của việc làm này là để đánh số cho các bức ảnh. Bằng cách thêm một thuộc tính mới và gán giá trị trong mỗi thẻ image như sau:

<img class="slide" src="img/picture1.jpg" idx="0" alt="">
<img class="slide" src="img/picture2.jpg" idx="1" alt="">
<img class="slide" src="img/picture3.jpg" idx="2" alt="">
<img class="slide" src="img/picture4.jpg" idx="3" alt="" >

Tương tự với 4 button

<button class="active" idx="0">1</button>
<button idx="1">2</button>
<button idx="2">3</button>
<button idx="3">4</button>

Giờ thì mỗi bức ảnh đã được gán vị trí nhờ thuộc tính idx. Tiếp đến, bạn chuyển sang script.js để tiến hành gán giá trị xác định ảnh đầu và ảnh cuối

var stt = 0;
var endImg = $("img.slide:last").attr("idx");

3.2 Thêm sự kiện cho 4 button số

$("button").click(function() {
    stt = $(this).attr("idx");
    
    $("img.slide").hide();
    $("img.slide").eq(stt).show();
    $("button").removeClass("active");
    $("button").eq(stt).addClass("active");
});

Tư tưởng của đoạn code như sau: Khi click vào 1 trong 4 button thì ...

  • Biến stt sẽ nhận số chỉ của button nhận sự kiện click qua thuộc tính idx.
  • Ẩn toàn bộ ảnh trong slide
  • Hiện thị ảnh có số chỉ stt (Chính là ảnh có vị trí tương ứng với button bạn click)
  • Xóa class active với tất cả các button và set lại class active cho button nhận sự kiện click

3.3 Code sự kiện cho 2 button chuyển slide

Tương tự ta tiến hành code cho 2 button chuyển slide

$("#next").click(function () {
    if (++stt > endImg) {
        stt = 0;
    }

    $("img.slide").hide();
    $("img.slide").eq(stt).show();
    $("button").removeClass("active");
    $("button").eq(stt).addClass("active");
});

$("#prev").click(function () {
    if (--stt < 0) {
        stt = endImg;
    }

    $("img.slide").hide();
    $("img.slide").eq(stt).show();
    $("button").removeClass("active");
    $("button").eq(stt).addClass("active");
});

Tại đây các bạn lưu ý một chút về đoạn xử lý vấn đề:

  • Khi ảnh số 4 đang hiện thị và button next nhận sự kiện
  • Khi ảnh số 1 đang hiện thị và button prev nhận sự kiện

Giải pháp: Bạn phải tăng hoặc giảm stt đi 1 đơn vị. Sau đó so sánh xem, stt có nằm ngoài khoảng từ 0-3 hay không. Nếu vi phạm điều kiện thì phải đặt lại giá trị cho stt.

Lưu ý:

  • ++x: Tăng x lên 1 đơn vị rồi thực thi dòng code đó.
  • x++: Sử dụng x để thực thi dòng code. Khi dòng code kết thúc thì mới tăng x lên 1 đơn vị.

3.4 Đặt khoảng thời gian tự động chuyển slide

var interval;
var timer = function () {
    interval = setInterval(function () {
        $("#next").click();
    }, 5000);
};

timer();

Lý do mà mình viết code có chút dài dòng hơn bình thường sẽ đước giải thích ở phần dưới nhé!

3.5 Tối ưu code

Các bạn có nhận ra đoạn code này lặp lại khá nhiều không?

$("img.slide").hide();
$("img.slide").eq(stt).show();
$("button").removeClass("active");
$("button").eq(stt).addClass("active");

Giải pháp là các bạn có thể đưa đoạn code này vào một hàm và tái sử dụng lại nó

var changeImg = function(stt) {
    $("img.slide").hide();
    $("img.slide").eq(stt).show();
    $("button").removeClass("active");
    $("button").eq(stt).addClass("active");
    
    clearInterval(interval);
    timer();
};

$("button").click(function() {
    stt = $(this).attr("idx");
    
    changeImg(stt);
});

$("#next").click(function() {
    if(++stt > endImg) {
        stt = 0;
    }
    
    changeImg(stt);
});

$("#prev").click(function() {
    if(--stt < 0) {
        stt = endImg;
    }
    
    changeImg(stt);
});

Giờ mình sẽ giải thích về cách mình viết hàm timer(). Đó là vì nếu bạn chỉ sử dụng đoạn code sau ở cuối hàm $(document).ready()

setInterval(function () {
        $("#next").click();
    }, 5000);

Thì sẽ xảy ra một vấn đề là khi timer() chạy đến khoảng 2000ms mà sự kiện chuyển slide diễn ra thì chỉ sau 500ms-1000ms sự kiện chuyển slide lại được kích hoạt tiếp. Điều này sẽ tạo ra tạo trải nghiệm rất khó chịu cho người dùng.

Giải pháp: Đó là code như mình! Đùa vậy thôi, có khá nhiều cách xử lý khác nhau. Nhưng mình chọn cách "gói" đoạn code tự động chuyển slide vào 1 hàm tên là timer(). Cùng với đó là lưu setInterval() vào một biến. Sau đó khi mà sự kiện chuyển slide xảy ra (tức là hàm changeImg() được gọi thì setInterval() sẽ được reset và gọi lại timer() để thời gian được đặt lại từ đầu.

3.6 Thêm hiệu ứng chuyển ảnh

Để cho quá trình chuyển slide trông đẹp hơn, bạn có thể thêm hiệu ứng cho nó bằng cách thay dòng code 

$("img.slide").eq(stt).show();

bằng dòng code

$("img.slide").eq(stt).fadeIn(500);

Phù! Cuối cùng thì cũng đã ra thành quả rồi!

Các bạn có thể xem toàn bộ source code tại link Github: https://github.com/pvtd264/slideUsingJquery

Bonus

Dưới đây là một link các bạn có thể tham khảo để thỏa sức sáng tạo thêm. Chúc các bạn thành công!