得到一个粘性标题“推高”,就像使用CSS和jQuery的Instagram的iPhone应用程序
Instagram的应用程序有一个很好的粘头,推动当前的一个,而不是新的。 我发现了一个很好的教程,如何为Android本身做到这一点,但我期待着用JavaScript和CSS做到这一点。
我能够得到我的标题,以换一个新的,但我似乎无法find一种模仿Instagram的方式。 任何帮助是极大的赞赏。
* 编辑:我能够得到标题坚持页面顶部滚动时使用航点作为Cj在评论指出。 ( 链接到航点 )。 我遇到的主要问题是让instagram在他们的iPhone移动应用程序中使用的“推高”效果。 我会链接到一个例子,但我从来没有见过它用过。 *
* *编辑2:使用@Chris提供的codepen的部分我能够得到标题坚持。 然后我添加了.slideUp效果。 我现在的问题是只有在达到下一个标题时才会发生.slideUp效果。 现在效果在滚动上激活。
这里是代码:
(function() { function stickyTitles(stickies) { this.load = function() { stickies.each(function(){ var thisSticky = jQuery(this); jQuery.data(thisSticky[0], 'pos', thisSticky.offset().top); }); } this.scroll = function() { stickies.each(function(){ var thisSticky = jQuery(this), pos = jQuery.data(thisSticky[0], 'pos'); if (pos <= jQuery(window).scrollTop()) { thisSticky.addClass("fixed"); // added this $(".followMeBar:parent").slideUp(); } else { thisSticky.removeClass("fixed"); } }); } } jQuery(document).ready(function(){ var newStickies = new stickyTitles(jQuery(".followMeBar")); newStickies.load(); jQuery(window).on("scroll", function() { newStickies.scroll(); }); });
})();
没有一个快速或简单的答案,但有一点创意cajoling我们可以模拟相同的function。
我们需要的是我们可以识别的一系列元素,循环并设置,以便当我们在页面上的位置上移时,上一个项目被推上,新项目变得固定。 我们需要使用jQuery的offset().top
方法检索元素的初始位置,并将其存储在data
标签中,以便稍后参考。 其余的将在我们滚动时计算。
这应该做的伎俩:
var stickyHeaders = (function() { var $window = $(window), $stickies; var load = function(stickies) { if (typeof stickies === "object" && stickies instanceof jQuery && stickies.length > 0) { $stickies = stickies.each(function() { var $thisSticky = $(this).wrap('<div class="followWrap" />'); $thisSticky .data('originalPosition', $thisSticky.offset().top) .data('originalHeight', $thisSticky.outerHeight()) .parent() .height($thisSticky.outerHeight()); }); $window.off("scroll.stickies").on("scroll.stickies", function() { _whenScrolling(); }); } }; var _whenScrolling = function() { $stickies.each(function(i) { var $thisSticky = $(this), $stickyPosition = $thisSticky.data('originalPosition'); if ($stickyPosition <= $window.scrollTop()) { var $nextSticky = $stickies.eq(i + 1), $nextStickyPosition = $nextSticky.data('originalPosition') - $thisSticky.data('originalHeight'); $thisSticky.addClass("fixed"); if ($nextSticky.length > 0 && $thisSticky.offset().top >= $nextStickyPosition) { $thisSticky.addClass("absolute").css("top", $nextStickyPosition); } } else { var $prevSticky = $stickies.eq(i - 1); $thisSticky.removeClass("fixed"); if ($prevSticky.length > 0 && $window.scrollTop() <= $thisSticky.data('originalPosition') - $thisSticky.data('originalHeight')) { $prevSticky.removeClass("absolute").removeAttr("style"); } } }); }; return { load: load }; })(); $(function() { stickyHeaders.load($(".followMeBar")); });
.followMeBar { background: #999; padding: 10px 20px; position: relative; z-index: 1; color: #fff; } .followMeBar.fixed { position: fixed; top: 0; width: 100%; box-sizing: border-box; z-index: 0; } .followMeBar.fixed.absolute { position: absolute; } /* For aesthetics only */ body { margin: 0; font-family: Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="followMeBar">A</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">B</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">C</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">D</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">E</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">F</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">G</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">H</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">I</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">J</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">K</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">L</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">M</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">N</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">O</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">P</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">Q</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">R</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">S</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">T</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">U</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">V</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">W</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">X</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">Y</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <div class="followMeBar">Z</div> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br>
首先,感谢@Chris Spittles的杰出回答。
我创build了一个修改版本,它不需要包装每个粘性元素,因为它只是改变它们的相对位置,而不是使用固定的位置。
var stickyHeaders = (function() { var $stickies; var load = function(stickies, target) { if (typeof stickies === "object" && stickies instanceof jQuery && stickies.length > 0) { $stickies = stickies.each(function() { var $thisSticky = $(this); $thisSticky .data('originalPosition', $thisSticky.offset().top) .data('originalHeight', $thisSticky.outerHeight()); }); target.off("scroll.stickies").on("scroll.stickies", function(event) { _whenScrolling(event); }); } }; var _whenScrolling = function(event) { var $scrollTop = $(event.currentTarget).scrollTop(); $stickies.each(function(i) { var $thisSticky = $(this), $stickyPosition = $thisSticky.data('originalPosition'), $newPosition, $nextSticky; if ($stickyPosition <= $scrollTop) { $newPosition = Math.max(0, $scrollTop - $stickyPosition); $nextSticky = $stickies.eq(i + 1); if($nextSticky.length > 0) { $newPosition = Math.min($newPosition, ($nextSticky.data('originalPosition') - $stickyPosition) - $thisSticky.data('originalHeight')); } } else { $newPosition = 0; } $thisSticky.css('transform', 'translateY(' + $newPosition + 'px)'); //could just as easily use top instead of transform //$thisSticky.css('top', $newPosition + 'px'); }); }; return { load: load }; })(); $(function() { stickyHeaders.load($(".followMeBar"), $(window)); });
CSS简化为:
.followMeBar { background: #999; padding: 10px 20px; position: relative; z-index: 1; color: #fff; } /* For aesthetics only */ body { margin: 0; font-family: Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif; }
http://plnkr.co/edit/wk3h40LfBdN1UFtDLZgY?p=preview
下面是另一个例子,展示了如何使用固定头文件时可以有一个偏移量:
我尝试了上面提供的解决scheme,但没有一个没有bug(主要是滚动和浏览器兼容性的bug)没有完美的工作。 刚刚发现这一个https://github.com/sarahdayan/feedify ,它对我很好。
我得到克里斯的答案准确地为我工作,因为所有的贴纸都是在一个相对定位的div(头部上面是所有的,在相对div之外) – 答案就是存储.offset() 。var的相对容器div的顶部,并从脚本中的.css('top', value )中减去它。 正如在克里斯的版本,最高价值推动文件的顶部工作正常。 当你添加相对div时,top现在是从顶端推入,所以相对div上面的任何空间都包含在你不想要的值中。 希望这可以帮助别人。 詹姆士
解决scheme的基本版本:
CSS
.sectionWrapper{ background-color: #1E1E1E; padding: 10px 20px; color: #FF7B05; width: 100% height: 45px; min-height: 45px; margin-top: 30px; position: relative; z-index: 10; } .sectionHeader{ } .sectionEmbed { } .sectionFixed { background-color: #1E1E1E; padding: 10px 20px; color: #FF7B05; width: 100%; height: 45px; position: fixed; top: 0; left: 0; margin: 0; }
HTML
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 sectionWrapper sectionEmbed"> <div class="sectionHeader">Headers here</div> </div>
JQuery的
//check doc is ready $(function() { $(window).on("scroll.sectionWrapper", function() { stickSections(); }); }); //function stickSection function stickSections() { //detach the listener $(window).off("scroll.sectionWrapper"); $scrollPos = $(window).scrollTop(); $currentSticky = null; $('.sectionWrapper').each(function(){ $(this).children().removeClass('sectionFixed'); if($scrollPos >= ($(this).offset().top - ($(this).height() - $(this).children().height() - 6)) ){ $currentSticky = $(this); } else $(this).children().addClass('sectionEmbed'); }); //apply the fixed class to our scrollPos match if($currentSticky) $currentSticky.children().addClass('sectionFixed'); //reattach the listener $(window).on("scroll.sectionWrapper", function() { stickSections(); }); }
例
https://codepen.io/ZombiesByte/pen/EyYwVO
玩的开心 :)
如果div的内容超出了粘滞标题,这并不总是奏效: $thisSticky.css('transform', 'translateY(' + $newPosition+ 'px)');
但是,这条线的窍门//could just as easily use top instead of transform $thisSticky.css('top', $newPosition+ 'px');
有一个固定的jQuery库。