고정 사이드 바 : 아래로 스크롤하면 하단에 고정, 위로 스크롤하면 상단에 고정
나는 끈적 끈적한 사이드 바 문제에 대한 해결책을 찾고 있습니다. 나는 그것이 어떻게 행동하고 싶은지에 대한 구체적인 아이디어를 가지고 있습니다. 효과적으로, 나는 당신이 아래로 스크롤 할 때 바닥에 붙어 있길 원하고, 다시 위로 스크롤하자마자 유동적 인 동작 (점프 없음)으로 맨 위에 붙어 있길 원합니다. 내가 달성하려는 것의 예를 찾을 수 없으므로 요점을 더 명확하게 설명 할 수있는 이미지를 만들었습니다.
- 사이드 바는 헤더 아래에 있습니다.
- 아래로 스크롤 할 때 사이드 바는 페이지 콘텐츠와 수평을 유지하므로 사이드 바와 콘텐츠를 모두 스크롤 할 수 있습니다.
- 사이드 바의 하단에 도달하면 사이드 바가 뷰포트 하단에 고정됩니다 (대부분의 플러그인은 상단 고정 만 허용하고 일부 플러그인은 하단 고정을 허용하는 것은 둘 다 허용하지 않음).
- 하단에 도달하면 사이드 바가 바닥 글 위에 있습니다.
- 위로 스크롤하면 사이드 바는 콘텐츠와 수평을 유지하므로 콘텐츠와 사이드 바를 다시 스크롤 할 수 있습니다.
- 사이드 바의 상단에 도달하면 사이드 바가 뷰포트 상단에 고정됩니다.
- 상단에 도달하면 사이드 바가 헤더 아래에 있습니다.
이것이 충분한 정보가되기를 바랍니다. 이 질문에 대해 재설정 한 플러그인 / 스크립트를 테스트하기 위해 jsfiddle을 만들었습니다 : http://jsfiddle.net/jslucas/yr9gV/2/ .
아주 멋지고 그림 같은 이미지에 +1 합니다.
나는 그것이 오래된 질문이라는 것을 알고 있지만 우연히 forum.jquery.com에 게시 된 동일한 질문 과 거기에 하나의 답변 (by @ tucker973) 을 발견하고이를 만들기 위해 멋진 라이브러리 하나를 제안했으며 여기에서 공유하고 싶었습니다.
그것은라고 끈적 키트 로 @leafo
- github proyect
- 웹 페이지
- jsFiddle의 간단한 예제 (여기에 첨부 된 스 니펫과 동일한 코드)
여기에 제가 준비한 매우 기본적인 예제 코드와 결과를보기위한 작업 데모가 있습니다.
/*!
* Sticky-kit
* A jQuery plugin for making smart sticky elements
*
* Source: http://leafo.net/sticky-kit/
*/
$(function() {
$(".sidebar").stick_in_parent({
offset_top: 10
});
});
* {
font-size: 10px;
color: #333;
box-sizing: border-box;
}
.wrapper,
.header,
.main,
.footer {
padding: 10px;
position: relative;
}
.wrapper {
border: 1px solid #333;
background-color: #f5f5f5;
padding: 10px;
}
.header {
background-color: #6289AE;
margin-bottom: 10px;
height: 100px;
}
.sidebar {
position: absolute;
padding: 10px;
background-color: #ccc;
height: 300px;
width: 100px;
float: left;
}
.main {
background-color: #ccc;
height: 600px;
margin-left: 110px;
}
.footer {
background-color: #6289AE;
margin-top: 10px;
height: 250px;
}
.top {
position: absolute;
top: 10px;
}
.bottom {
position: absolute;
bottom: 10px;
}
.clear {
clear: both;
float: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://leafo.net/sticky-kit/src/jquery.sticky-kit.js"></script>
<div class="wrapper">
<div class="header"> <a class="top">header top</a>
<a class="bottom">header bottom</a>
</div>
<div class="content">
<div class="sidebar"> <a class="top">sidebar top</a>
<a class="bottom">sidebar bottom</a>
</div>
<div class="main"> <a class="top">main top</a>
<a class="bottom">main bottom</a>
</div>
<div class="clear"></div>
</div>
<div class="footer"> <a class="top">footer top</a>
<a class="bottom">footer bottom</a>
</div>
</div>
물론 모든 크레딧은 플러그인 제작자에게 전달됩니다. 여기서 보여 드리기 위해이 예제 만 만들었습니다. 나는 당신이 추구했던 것과 동일한 결과를 달성해야 하며이 플러그인이 매우 유용하다는 것을 알았습니다.
멋진 그래픽에 감사드립니다. 나는 또한이 도전에 대한 해결책을 찾고 있었다!
불행히도 여기에 게시 된 다른 답변은 사이드 바를 부드럽게 뒤로 스크롤하는 기능을 규정하는 요구 사항 # 5를 다루지 않습니다.
모든 요구 사항을 구현하는 바이올린을 만들었습니다. http://jsfiddle.net/bN4qu/5/
구현해야하는 핵심 로직은 다음과 같습니다.
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
바이올린에서는 대상 요소를 이동하기 위해 CSS3 변환을 사용하므로 IE <9에서는 작동하지 않습니다. 논리는 다른 접근 방식을 사용하는 것이 좋습니다.
또한 스티커 사이드 바에 그라데이션 배경이 있도록 바이올린을 수정했습니다. 이것은 적절한 행동이 나타나고 있음을 보여주는 데 도움이됩니다.
누군가에게 유용하기를 바랍니다!
이를 구현하는 방법의 예는 다음과 같습니다.
자바 스크립트 :
$(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%;
}
데모 : http://jsfiddle.net/ryanmaxwell/25QaE/
이것은 모든 시나리오에서 예상대로 작동하며 IE에서도 잘 지원됩니다.
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");
Working Example: https://jsfiddle.net/L7xoopst/6/
There is a relatively unknown plugin in Wordpress repository known as WP Sticky Sidebar. The plugin does exactly what you wanted (Sticky sidebar: stick to bottom when scrolling down, top when scrolling up) WP Sticky Sidebar Wordpress repository Link: https://wordpress.org/plugins/mystickysidebar/
I was looking for the exact same thing. Apparently I needed to search for some obscure terms just to find a similar question with the graphic. Turns out it's exactly what I was looking for. I couldn't find any plugins so I decided to make it myself. Hopefully someone will see this and refine it.
Here's a quick and dirty sample html I'm using.
<div id="main">
<div class="col-1">
</div>
<div class="col-2">
<div class="side-wrapper">
sidebar content
</div>
</div>
</div>
Here's the jQuery I made:
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();
});
}
Some notes:
- .rectbtfad is the bottom most element in my sidebar
- # 마스트 헤드의 높이를 사용하고 있습니다. 고정 헤더이기 때문에이를 보완해야합니다.
- 반응 형 디자인을 사용하고 있으며 더 작은 화면에서 활성화되는 것을 원하지 않기 때문에 col-2 float에 대한 검사가 있습니다.
누군가 이것을 조금 더 다듬을 수 있다면 좋을 것입니다.
'Development Tip' 카테고리의 다른 글
Google 크롬 확장 프로그램에서 프로그래밍 방식으로 devtools를 열 수 있나요? (0) | 2020.10.27 |
---|---|
때때로`git stash -p`가 실패하는 이유는 무엇입니까? (0) | 2020.10.27 |
브라우저에서 Karma 테스트 출력을 보시겠습니까? (0) | 2020.10.27 |
ARKit vs. ARCore vs. Vuforia vs. D' Fusion Mobile vs. Layar SDK (0) | 2020.10.27 |
jsFiddle은 코드를 얼마나 오래 호스팅합니까? (0) | 2020.10.27 |