Bài hôm nay chúng ta cùng nhau tìm hiểu về cách làm cho một widget cố định khi scroll đến widget đó và phương pháp viết code bằng jquery thêm css vào widget để cố định widget lại. Lưu ý không nên sử dụng các plugin viết sẵn vì nó rất khó áp dụng vào các blog khác nhau.
Đọc thêm: Tìm hiểu về cách chặn font, css và js mặc định của Blogger
Cố định widget bên phải |
Trước khi viết code trước hết chúng ta cùng đi tìm hiểu về cơ chế cố định widget khi scroll đến nó
1. Chỉ cố định widget trên màn hình lớn thường là từ 860px trở lên
2. Loại trừ trên mobile
3. Xác định điểm đầu, điểm cuối và điểm cố định
Trường hợp 1: Giả sử chúng ta có 4 điểm được sắp xếp hiển thị như sau trong đó F là điểm cần cố định:
A (width:100%)B (width:70%) F (width:30%)
C (width:100%)
=> scroll đến chân của điềm A, cố định điểm F cho đến đầu của điểm C
Trường hợp 2: Chúng ta lại có 5 điểm được sắp xếp như sau:
A (width:100%)
B (width:70%) C (width:30%) F (width:30%)
D (width:100%)
=> scroll đến chân của điềm C, cố định điểm F cho đến đầu của điểm D
Đọc thêm: Tạo các hàm function để load tệp css và js từ nguồn bên ngoài
Từ 2 ví dụ ra chúng ta cần xác định những điểm sau:
Điểm cần cố định, điểm đứng ngay trên nó (điểm đầu) và điểm dưới chân nó (điểm cuối) để tạo cơ chế cố định khi scroll đến chân của điểm đầu và đến đầu của điềm cuối
Ngoài ra cần xác định header đầu trang có cố định hay không nếu header cố định cần tính độ cao của header để trừ ra.
Từ những điều kiện kết hợp ở trên để code như sau:
<b:if cond='!data:blog.isMobileRequest'>
<script>//<![CDATA[
window.addEventListener('load', function() {
var mq = window.matchMedia('(min-width:861px)')
if (mq.matches) { // Điều hiện màn hình kích thước từ 860px trở lên
var widget = $('.has-banner-fixed'), // Xác định element cần cố định
menu = $('header.header') // header đầu trang
x = $(widget).find('.fixed-on-scroll'), // element con bên trong, thay x = $(widget) nếu muốn cố định element cha
y = $(widget).prev(), // Điểm đầu, thay y = $(widget).prev().prev() nếu áp dụng cho trường hợp 1 hoặc thay y = $('.element') nếu phía trên nó là header ví dụ $('.header')
z = $(widget).next() // Điểm cuối, thay z = $('.element') ví dụ $('.footer-wrapper') nếu bên dưới điểm cố định không có điểm cuối
if (widget) {
function scroll_to_fiexed() {
var d = $(window).scrollTop(),
e = z.offset().top,
f = y.offset().top + y.outerHeight(),
g = x.height(),
h = 20;
if (d + g > e - h) x.css({ // Điều kiện khi scroll đến đầu điểm cuối
'top': (d + g - e + h) * -1,
'z-index': 0
})
else if (d > f) x.css({ // Điều kiện khi scroll đến chân điểm đầu
'position': 'fixed',
'top': menu.outerHeight(), // thay 'top':0 nếu header không cố định
'left': x.offset().left,
'width': x.outerWidth(),
'z-index': 1000
})
else x.removeAttr('style')
}
$(window).scroll(scroll_to_fiexed)
scroll_to_fiexed()
window.addEventListener('resize', function() {
if (this.matchMedia('(max-width:860px)').matches) $(widget).hide()
else $(widget).show()
})
}
}
})
//]]></script>
</b:if>
Đọc thêm: Quy tắc đặt @media với thuộc tính min-width và max-width đúng cách khi viết css
Mở rộng với trường hợp nếu một trang có nhiều widget giống nhau cần cố định sắp xếp từ trên xuống dưới, chúng ta sẽ đưa các widget vào vòng lặp như sau:
<b:if cond='!data:blog.isMobileRequest'>
<script>//<![CDATA[
window.addEventListener('load', function() {
var mq = window.matchMedia('(min-width:861px)')
if (mq.matches) {
var widget = $('.has-banner-fixed'),
menu = $('header.header')
if (widget) {
$(widget).each(function(i) {
var x = $(widget[i]).find('.fixed-on-scroll'),
y = $(widget[i]).prev(),
z = $(widget[i]).next()
function scroll_to_fiexed() {
var d = $(window).scrollTop(),
e = z.offset().top,
f = y.offset().top + y.outerHeight(),
g = x.height(),
h = 20
if (d + g > e - h) x.css({
'top': (d + g - e + h) * -1,
'z-index': 0
})
else if (d > f) x.css({
'position': 'fixed',
'top': menu.outerHeight(),
'left': x.offset().left,
'width': x.outerWidth(),
'z-index': 1000
})
else x.removeAttr('style')
}
$(window).scroll(scroll_to_fiexed)
scroll_to_fiexed()
window.addEventListener('resize', function() {
if (this.matchMedia('(max-width:860px)').matches) $(widget[i]).hide()
else $(widget[i]).show()
})
})
}
}
})
//]]></script>
</b:if>
Đọc thêm: Giới thiệu một số hiệu ứng toàn trang đẹp thường được sử dụng trong thiết kế web