スティッキーサイドバーの問題の解決策を探していました。私はそれがどのように行動したいかという特定の考えを持っています。事実上、下にスクロールすると下に固定され、上にスクロールするとすぐに上に固定され、流動的な動き(ジャンプなし)になります。私が達成しようとしているものの例を見つけることができないので、私はポイントをより明確に説明することを望んでいるイメージを作成しました:
これで十分な情報になることを願っています。プラグイン/スクリプトをテストするためにjsfiddleを作成しましたが、この質問に対してリセットしました: http://jsfiddle.net/jslucas/yr9gV/2/.
+ 1とても素敵でイラスト入りの画像に。
私はそれが古い質問であることを知っていますが、あなたが forum.jquery.com に投稿した同じ質問を偶然見つけました。 (by @ tucker973)、これを作成するニースライブラリを提案し、ここで共有したいと考えました。
sticky-kitby@ leafo
ここに、私が準備した非常に基本的な例のコードと、結果を見るための実際のデモがあります。
/*!
* 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。しかし、異なるアプローチを使用するためのロジックは健全です。
また、スティッキーサイドバーの背景がグラデーションになるようにフィドルを修正しました。これは、適切な動作が示されていることを示すのに役立ちます。
これが誰かに役立つことを願っています!
これを実装する方法の例を次に示します。
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%;
}
デモ: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");
WordpressリポジトリWPスティッキーサイドバー。プラグインはまさにあなたが望んだことをします。 、上にスクロールするときにトップ)WP Sticky Sidebar Wordpress repository Link: https://wordpress.org/plugins/mystickysidebar/
私はまったく同じものを探していました。どうやら、グラフィックで同様の質問を見つけるために、いくつかのあいまいな用語を検索する必要があったようです。まさに私が探していたものであることがわかりました。プラグインが見つからなかったため、自分で作成することにしました。誰かがこれを見て、それを改良することを願っています。
ここに私が使用している迅速で汚いサンプルhtmlがあります。
<div id="main">
<div class="col-1">
</div>
<div class="col-2">
<div class="side-wrapper">
sidebar content
</div>
</div>
</div>
これが私が作成したjQueryです。
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();
});
}
いくつかのメモ:
誰かがこれをもう少し改良できるなら、それは素晴らしいことです。