Saya telah mencari beberapa waktu sekarang untuk solusi untuk masalah bilah sisi lengket saya. Saya memiliki gagasan khusus tentang bagaimana saya ingin ia bertindak; secara efektif, saya ingin papan itu menempel di bagian bawah saat Anda menggulir ke bawah, dan segera setelah Anda menggulir kembali ke atas, saya ingin papan itu tetap di atas, dalam gerakan yang mengalir (tidak ada lompatan). Saya tidak dapat menemukan contoh dari apa yang saya coba capai, jadi saya telah membuat gambar yang saya harap akan mengilustrasikan poin dengan lebih jelas:
- Sidebar berada di bawah header.
- Saat Anda menggulir ke bawah, bilah sisi tetap sejajar dengan konten halaman sehingga Anda dapat menggulir melalui bilah sisi dan konten.
- Jangkau bagian bawah sidebar, sidebar menempel ke bagian bawah viewport (kebanyakan plugin hanya memungkinkan untuk menempel di atas, beberapa yang memungkinkan untuk menempel ke bawah tidak memungkinkan untuk keduanya).
- Capai bagian bawah, sidebar berada di atas footer.
- Saat Anda menggulir kembali ke atas, bilah sisi tetap sejajar dengan konten sehingga Anda dapat menggulir kembali konten dan bilah sisi.
- Jangkau bagian atas bar samping, bar samping menempel ke bagian atas viewport.
- Capai bagian atas dan sidebar berada kembali di bawah header.
Saya harap ini cukup informasi. Saya telah membuat jsfiddle untuk menguji plugin / skrip apa pun, yang telah saya setel ulang untuk pertanyaan ini: http://jsfiddle.net/jslucas/yr9gV/2/ .
Terima kasih untuk grafik yang bagus. Saya juga mencari solusi untuk tantangan ini!
Sayangnya, jawaban lain yang diposting di sini tidak memenuhi persyaratan # 5 yang menetapkan kemampuan untuk menggulir kembali bilah sisi dengan lancar.
Saya membuat biola yang menerapkan semua persyaratan: http://jsfiddle.net/bN4qu/5/
Logika inti yang perlu diimplementasikan adalah:
If scrolling up OR the element is shorter than viewport Then Set top of element to top of viewport If scrolled above top of element If scrolling down then Set bottom of element at bottom of viewport If scrolled past bottom of element
Di biola saya menggunakan transformasi CSS3 untuk memindahkan elemen target, jadi itu tidak akan berfungsi di misalnya IE <9. Logikanya masuk akal untuk menggunakan pendekatan yang berbeda.
Juga, saya memodifikasi biola Anda sehingga bilah sisi yang lengket memiliki latar belakang gradien. Ini membantu untuk menunjukkan bahwa perilaku yang tepat sedang ditampilkan.
Saya harap ini bermanfaat bagi seseorang!
sumber
$.css
fungsi dalam arequestAnimationFrame
dan menambahkan fungsi penghancuran / pelepasan untuk digunakan dalam kerangka kerja frontend modern seperti vue / react. Performa sama sekali bukan masalah setelah itu!Berikut adalah contoh bagaimana menerapkan ini:
JavaScript:
$(function() { var $window = $(window); var lastScrollTop = $window.scrollTop(); var wasScrollingDown = true; var $sidebar = $("#sidebar"); if ($sidebar.length > 0) { var initialSidebarTop = $sidebar.position().top; $window.scroll(function(event) { var windowHeight = $window.height(); var sidebarHeight = $sidebar.outerHeight(); var scrollTop = $window.scrollTop(); var scrollBottom = scrollTop + windowHeight; var sidebarTop = $sidebar.position().top; var sidebarBottom = sidebarTop + sidebarHeight; var heightDelta = Math.abs(windowHeight - sidebarHeight); var scrollDelta = lastScrollTop - scrollTop; var isScrollingDown = (scrollTop > lastScrollTop); var isWindowLarger = (windowHeight > sidebarHeight); if ((isWindowLarger && scrollTop > initialSidebarTop) || (!isWindowLarger && scrollTop > initialSidebarTop + heightDelta)) { $sidebar.addClass('fixed'); } else if (!isScrollingDown && scrollTop <= initialSidebarTop) { $sidebar.removeClass('fixed'); } var dragBottomDown = (sidebarBottom <= scrollBottom && isScrollingDown); var dragTopUp = (sidebarTop >= scrollTop && !isScrollingDown); if (dragBottomDown) { if (isWindowLarger) { $sidebar.css('top', 0); } else { $sidebar.css('top', -heightDelta); } } else if (dragTopUp) { $sidebar.css('top', 0); } else if ($sidebar.hasClass('fixed')) { var currentTop = parseInt($sidebar.css('top'), 10); var minTop = -heightDelta; var scrolledTop = currentTop + scrollDelta; var isPageAtBottom = (scrollTop + windowHeight >= $(document).height()); var newTop = (isPageAtBottom) ? minTop : scrolledTop; $sidebar.css('top', newTop); } lastScrollTop = scrollTop; wasScrollingDown = isScrollingDown; }); } });
CSS:
#sidebar { width: 180px; padding: 10px; background: red; float: right; } .fixed { position: fixed; right: 50%; margin-right: -50%; }
Demo: http://jsfiddle.net/ryanmaxwell/25QaE/
Ini berfungsi seperti yang diharapkan di semua skenario dan juga didukung dengan baik di IE.
sumber
Saya mencari hal yang persis sama. Rupanya saya perlu mencari beberapa istilah yang tidak jelas hanya untuk menemukan pertanyaan yang mirip dengan grafik. Ternyata itulah yang saya cari. Saya tidak dapat menemukan plugin apa pun, jadi saya memutuskan untuk membuatnya sendiri. Semoga seseorang akan melihat ini dan memperbaikinya.
Ini contoh html cepat dan kotor yang saya gunakan.
<div id="main"> <div class="col-1"> </div> <div class="col-2"> <div class="side-wrapper"> sidebar content </div> </div> </div>
Inilah jQuery yang saya buat:
var lastScrollPos = $(window).scrollTop(); var originalPos = $('.side-wrapper').offset().top; if ($('.col-2').css('float') != 'none') { $(window).scroll(function(){ var rectbtfadPos = $('.rectbtfad').offset().top + $('.rectbtfad').height(); // scroll up direction if ( lastScrollPos > $(window).scrollTop() ) { // unstick if scrolling the opposite direction so content will scroll with user if ($('.side-wrapper').css('position') == 'fixed') { $('.side-wrapper').css({ 'position': 'absolute', 'top': $('.side-wrapper').offset().top + 'px', 'bottom': 'auto' }); } // if has reached the original position, return to relative positioning if ( ($(window).scrollTop() + $('#masthead').height()) < originalPos ) { $('.side-wrapper').css({ 'position': 'relative', 'top': 'auto', 'bottom': 'auto' }); } // sticky to top if scroll past top of sidebar else if ( ($(window).scrollTop() + $('#masthead').height()) < $('.side-wrapper').offset().top && $('.side-wrapper').css('position') == 'absolute' ) { $('.side-wrapper').css({ 'position': 'fixed', 'top': 15 + $('#masthead').height() + 'px', // padding to compensate for sticky header 'bottom': 'auto' }); } } // scroll down else { // unstick if scrolling the opposite direction so content will scroll with user if ($('.side-wrapper').css('position') == 'fixed') { $('.side-wrapper').css({ 'position': 'absolute', 'top': $('.side-wrapper').offset().top + 'px', 'bottom': 'auto' }); } // check if rectbtfad (bottom most element) has reached the bottom if ( ($(window).scrollTop() + $(window).height()) > rectbtfadPos && $('.side-wrapper').css('position') != 'fixed' ) { $('.side-wrapper').css({ 'width': $('.col-2').width(), 'position': 'fixed', 'bottom': '0', 'top': 'auto' }); } } // set last scroll position to determine if scrolling up or down lastScrollPos = $(window).scrollTop(); }); }
Beberapa catatan:
Jika ada yang bisa menyempurnakan ini sedikit lebih banyak, itu akan bagus.
sumber
function fixMe(id) { var e = $(id); var lastScrollTop = 0; var firstOffset = e.offset().top; var lastA = e.offset().top; var isFixed = false; $(window).scroll(function(event){ if (isFixed) { return; } var a = e.offset().top; var b = e.height(); var c = $(window).height(); var d = $(window).scrollTop(); if (b <= c - a) { e.css({position: "fixed"}); isFixed = true; return; } if (d > lastScrollTop){ // scroll down if (e.css("position") != "fixed" && c + d >= a + b) { e.css({position: "fixed", bottom: 0, top: "auto"}); } if (a - d >= firstOffset) { e.css({position: "absolute", bottom: "auto", top: lastA}); } } else { // scroll up if (a - d >= firstOffset) { if (e.css("position") != "fixed") { e.css({position: "fixed", bottom: "auto", top: firstOffset}); } } else { if (e.css("position") != "absolute") { e.css({position: "absolute", bottom: "auto", top: lastA}); } } } lastScrollTop = d; lastA = a; }); } fixMe("#stick");
Contoh Kerja: https://jsfiddle.net/L7xoopst/6/
sumber
Ada plugin yang relatif tidak dikenal di repositori Wordpress yang dikenal sebagai WP Sticky Sidebar. Plugin melakukan apa yang Anda inginkan (Sticky sidebar: menempel ke bawah saat menggulir ke bawah, atas saat menggulir ke atas) WP Sticky Sidebar Wordpress repositori Tautan: https://wordpress.org/plugins/mystickysidebar/
sumber