Tạo Lightbox Image

Tạo Lightbox Image

Ở bài học trước chúng ta đã tìm hiểu cách mở tab mới để hiển thị duy nhất nội dung của ảnh sau khi người dùng click lên ảnh trên trang.
Trong bài học này chúng ta sẽ tìm hiểu cách triển khai tính năng phóng to ảnh trên trang hiện tại khi người dùng click lên chúng thay vì mở ảnh ở tab mới. Tính năng phóng to ảnh ở trang hiện tại này còn được gọi là lightbox image.

Hiện nay khi thiết kế website thì tính năng lightbox thường được ưa chuộng để triển khải hơn mở ảnh ở tab mới. Điều này là bởi vì khi phóng to ảnh thì trình duyệt không cần phải gửi thêm yêu cầu để tải lại hình ảnh từ server nữa mà chỉ phóng to ảnh hiện có lên, ngược lại khi mở ảnh ở tab mới thì trình duyệt sẽ cần gửi một yêu cầu tới server để tải về ảnh qua đó giảm thiểu thời gian chờ đợi.

Thêm Mã HTML cho Lightbox

Đầu tiên chúng ta thêm vào mã HTML để hiển thị lightbox vào từng trang web hiện tại. Phía trước thẻ <div id="footer"> của các trang bạn thêm vào đoạn mã HTML sau:

<!-- Lightbox HTML -->
<div id="lightbox">

  <!-- nút đóng lightbox -->
  <span id="close-icon">&times;</span>

  <!-- ảnh sẽ hiển thị -->
  <img id="image-placeholder">
</div>

Ở trên bạn chú ý trong thẻ <img> chúng ta không thêm vào thuộc tính src bởi thuộc tính này sẽ được gán vào linh động tuỳ thuộc vào ảnh nào sẽ được phóng to.

Trang Trí Lightbox

Bây giờ chúng ta sẽ thêm mã CSS để trang trí cho lightbox mới được thêm vào. Trong tập tin main.css bạn thêm vào đoạn mã sau ngay trước đoạn mã CSS áp dụng cho sticky footer:

...

/* lightbox */
#lightbox {
    display: none; /* ẩn lightbox */
    position: fixed; /* cố định vị trí hiển thị lightbox */
    z-index: 99; /* hiển thị lightbox ở phía trước các box có vị trí fixed khác (nếu có) */
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    padding-top: 100px; /* cách đỉnh 100px */
    background-color: rgba(0,0,0,0.8); /* màu nền đen với opacity 80% */
}

/* sticky footer */
...

Đoạn mã trên trước tiên sẽ ẩn lightbox mà không hiển thị trên trang. Chúng ta sẽ sử dụng JavaScript để hiển thị lightbox chỉ khi nào người dùng click vào ảnh.

Ngoài ra bạn cũng thấy đoạn code trên sử dung position: fixed để cố định vị trí của lightbox kết hợp với width: 100%height: 100% và các thuộc tíh topleft để hiển thị lightbox trải toàn bộ chiều rộng và chiều cao của màn hình.

Triển Khai Lightbox

Sau khi thêm vào mã HTML và CSS áp dụng cho lightbox thì bây giờ chúng ta sẽ cần tiếp tục thêm vào mã JavaScript để gán động giá trị cho thuộc tính src của ảnh bên trong lightbox và hiển thị lại lightbox trên màn hình.

Trong tập tin script.js, bên trong vòng lặp for bạn comment đi đoạn code sử dụng addEventListener() được thêm vào ở bài học trước và thay vào đó thêm vào đoạn code sau:

...
for (var i = 0; i < images.length; i++) {
    var currentImage = images[i];

    var lightbox = document.getElementById('lightbox');

    var imagePlaceholder = document.getElementById('image-placeholder');

    currentImage.onclick = function() {
        // console.log(currentImage);

        imagePlaceholder.src = currentImage.src;
        lightbox.style.display = 'block';
    }
}

Ở đoạn code trên chúng ta sử dụng method getElementById() để lấy ra phần tử với giá trị id cho trước. Tiếp đó chúng ta đăng ký hàm lắng nghe cho sự kiện click bằng việc gán giá trị hàm lắng nghe cho thuộc tính .onclick của phần tử currentImage. Như vậy ở đây thay vì sử dụng phương thức addEventListener() như bài học trước thì bây giờ chúng ta sử dụng việc gán giá trị của hàm lắng nghe cho thuộc tính onclick. Cách làm này tốt hơn bởi vì một số phiên bản của trình duyệt Internet Explorer (IE) không hỗ trợ phương thức addEventListener().

Bên trong hàm lắng nghe chúng ta gán giá trị cho thuộc tính src của imagePlaceholder bằng giá trị thuộc tính src của ảnh được click đồng thời đặt lại giá trị cho thuộc tính CSS display của phần tử lightbox là block (tương đương với display: block).

Nếu bây giờ bạn tải lại trang home.html và kiểm tra bằng cách click chuột lên hình ảnh trong phần nội dung trang bạn sẽ thấy lỗi hiển thị ảnh như sau:

Để hiểu tại sao xảy ra lỗi trên bạn kích hoạt lại (bỏ dấu comment JavaScript) dòng console.log bên trong hàm lắng nghe và sau đó quay lại trình duyệt bật công cụ Developer Tools rồi tải lại trang. Lúc này nếu click vào tab Console trên thanh công cụ Developer Tools bạn sẽ thấy currentImage lúc này là phần tử img#image-place thay vì đáng ra phải là <img src="images/home.jpg" alt="Hình Ảnh Trang Chủ">:

Và lúc này lỗi hiển thị ảnh xảy ra do giá trị thuộc tính src của phần tử img#image-place vẫn là null do chúng ta không gán giá trị này cho phần tử ngay từ lúc ban đầu.

Tại sao trong khi chúng ta click vào phần tử img trong trang nhưng Console lại hiển thị giá trị của currentImage lúc này là img#image-placeholder trong lightbox?

Điều này là bởi vì khi hàm lắng nghe được gọi (hay call) thì nó sẽ lấy giá trị của biến currentImage là phần tử cuối cùng trong mảng images trả về ở vòng lặp for cuối cùng. Tức là với các biến được khai báo bên ngoài hàm thì giá trị thực tế của nó được sử dụng khi hàm được gọi là giá trị tại thời hiện tại của nó khi hàm được gọi chứ không phải giá trị lúc hàm được khai báo.

Để khắc phục lỗi trên chúng ta sẽ thay đổi biến currentImage trong hàm lắng nghe bằng cách sử dụng this như sau:

currentImage.onclick = function() {
    console.log(this);

    imagePlaceholder.src = this.getAttribute('src');
    lightbox.style.display = 'block';
}

Biến this ở trên chính là phần tử img được sử dụng để đăng ký hàm lắng nghe cho sự kiện click hay chính là phần tử img mà người dùng click.

Bây giờ nếu bạn kiểm tra lại bạn sẽ thấy lighbox hiển thị được đúng hình ảnh được click như trong hình dưới đây:

Tuy nhiên bạn cũng thấy ảnh trong lightbox lúc này chưa được canh giữa và chúng ta cần thêm đoạn CSS sau vào style.css để đạt được mục đích này:

...
#image-placeholder {
    margin: auto;
    display: block;
    width: 80%;
}

/* sticky footer */
...

Bạn hãy tải lại trang và click lên ảnh để kiểm tra lại kết quả một lần nữa:

Đóng Lightbox

Một phần việc cuối cùng trong bài học này đó là chúng ta cần thêm vào tính năng đóng lightbox khi người dùng click vào icon đóng hình chữ x tạo bởi thẻ HTML <span id="close-icon"></span>.

Trước tiên sau đoạn code CSS áp dụng cho #image-placeholder trong tập tin main.css bạn thêm vào đoạn code CSS trang trí cho icon đóng lighbox như sau:

#close-icon {
    position: absolute;
    top: 15px;
    right: 35px;
    color: #f1f1f1;
    font-size: 50px;
}

Trong đoạn code trên chúng ta sử dụng luật CSS position: relative để icon đóng này được hiển thị một cách tương đối so với phần tử mẹ của nó hay div#lightbox. Hay nói cách khác nó sẽ được định vị dựa trên vị trí của phần tử mẹ. Ngoài ra chúng ta cũng sử dụng các thuộc tính CSS là top và right để định vị chính xác vị trí của icon.

Bây giờ bạn tải lại trang và click vào ảnh để mở lightbox bạn sẽ thấy icon này hiển thị ở phía trên góc trái màn hình như sau:

Tuy nhiên chúng ta cần thêm code JavaScript để có thể tắt lightbox khi người dùng click vào icon này. Ở phía cuối tập tin script.js bạn thêm vào đoạn mã JavaScript sau:

...
var closeLightboxButton = document.getElementById('close-icon');

closeLightboxButton.onclick = function() { 
  document.getElementById('lightbox').style.display = 'none';
}

Đoạn code trên khá đơn giản và bạn đã có thể tự mình hiểu được ý nghĩa của chúng tại thời điểm này do đó tôi se không giải thích nữa. Để hoàn tất bài học bạn cần tải lại trang và kiểm tra lại tính năng đóng lightbox này.

10 bình luận


Đăng bình luận