【问题标题】:Make element fixed on scroll使元素固定在滚动上
【发布时间】:2013-03-18 18:22:23
【问题描述】:

当用户向下滚动到导航栏时,我试图让导航栏固定在顶部,然后当用户向上滚动到导航栏时取消固定。我知道这只能通过 JavaScript 来实现。我是 JavaScript 的初学者,所以越简单越好。 The JSFIDDLE is here.

HTML如下:

   <section class="main">
     <div id="wrap">
        <div id="featured">
     <div class="wrap">      
  <div class="textwidget">
    <div class="cup"><img src="#""></div>
<div id="header"></div></div></div></div></div></div></div>
<div class="whiteboard">
         <h1><a href="#">HELLO GUYS</a></h1> </div>
   </div>
          <div class="bg1">
            <h2> WE ARE AN EVENTS MANAGEMENT COMPANY BASED IN LONDON. </h2></div>

CSS如下:

      .main{text-align:center;}

      h1{
          -webkit-font-smoothing: antialiased;
              display:inline-block;
            font: 800 1.313em "proxima-nova",sans-serif; 
            padding: 10px 10px;
            margin: 20px 20px;
            letter-spacing: 8px;
            text-transform: uppercase;
              font-size:3.125em;
              text-align: center; 
              max-width: 606px;
      line-height: 1.45em;
      position: scroll;
          background-color:#e94f78;
          text-decoration: none;
          color:yellow;
          background-image:url;
      }

      h1 a{
        text-decoration: none;
        color:yellow;
                padding-left: 0.15em;
      }

      h2{
          -webkit-font-smoothing: antialiased;
              display:inline-block;
            font: 800 1.313em "proxima-nova",sans-serif; 
            letter-spacing: 8px;
            margin-top: 100px;
            text-transform: uppercase;
              font-size:3.125em;
              text-align: center; 
      line-height: 1.45em;
      position: scroll;
          text-decoration: none;
          color:white;
          z-index: -9999;
      }

      h2 a{
        text-decoration: none;
        color:white;
                padding-left: 0.15em;
      }

      h5{

      position: absolute;
              font-family:sans-serif; 
              font-weight:bold; 
              font-size:40px; 
              text-align: center; 
              float: right;
              background-color:#fff;
              margin-top: -80px;
              margin-left: 280px;
      }

      h5 a{

        text-decoration: none;
        color:red;
      }

      h5 a:hover{

        color:yellow;
      }

      #text1{
          -webkit-font-smoothing: antialiased;
              display:inline-block;
            font: 800 1.313em "proxima-nova",sans-serif; 
            margin: 20px 20px;
            letter-spacing: 8px;
            text-transform: uppercase;
              font-size:3.125em;
              text-align: center; 
              max-width: 606px;
      line-height: 1.45em;
      position: scroll;
          background-color:#E94F78;

      }

      #text1 a{
          color:yellow;
          text-decoration: none;
              padding-left: 0.15em;


      }

      #text1 a:hover{

          text-decoration: none;
          cursor:pointer;
      }

      .whiteboard{
          background-image:url(http://krystalrae.com/img/krystalrae-2012-fall-print-leopard-sketch.jpg);
          background-position: center;
          padding: ;
          background-color: #fff;
          z-index: 1000;
      }

      .bg{
        height:2000px;
        background-color:#ff0;
        background-image:url(http://alwayscreative.net/images/stars-last.jpg);
        position:relative;
        z-index: -9999;

      }
      .bg1{
        background-image:url(http://alwayscreative.net/images/stars-last.jpg);
        z-index: -9999;
        height:1000px;
      }
      /* Header */
      #wrap {
        margin: 0 auto;
        padding: 0;
        width: 100%;
      }

      #featured {
        background: #E94F78 url(http://www.creativityfluid.com/wp-content/themes/creativityfluid/images/img-bubbles-red.png) no-repeat top;
        background-size: 385px 465px;
        color: #fff;
        height: 535px;
        overflow: hidden;
        position: relative;
        z-index: -2;
      }


      #featured .wrap {
        overflow: hidden;
        clear: both;
        padding: 70px 0 30px;
        position: fixed;
        z-index: -1;
        width: 100%;
      }


      #featured .wrap .widget {
        width: 80%;
        max-width: 1040px;
        margin: 0 auto;
      }

      #featured h1,
      #featured h3,
      #featured p {
        color: yellow;
        text-shadow: none;
      }

      #featured h4{
        color:white;
        text-shadow:none;
      }

      #featured h4 {
        margin: 0 0 30px;
      }

      #featured h3 {
        font-family: 'proxima-nova-sc-osf', arial, serif;
        font-weight: 600;
        letter-spacing: 3px;
      }

      #featured h1 {
        margin: 0;
      }

      .textwidget{
        padding: 0;
      }

      .cup{
        margin-top:210px;
        z-index: 999999;
      }

      .container{font-size:14px; margin:0 auto; width:960px}
      .test_content{margin:10px 0;}
      .scroller_anchor{height:0px; margin:0; padding:0;background-image:url()}
      .scroller{background:#FFF;
        background-image:url(http://krystalrae.com/img/krystalrae-2012-fall-print-leopard-sketch.jpg);
       margin:0 0 10px; z-index:100; height:50px; font-size:18px; font-weight:bold; text-align:center; width:960px;}

【问题讨论】:

  • 为什么说你是JAVA的初学者?也许你的意思是 JavaScript?请记住,除了名称中的公共前缀之外,JavaScript 与 JAVA 完全无关:P
  • 是的,JavaScript 之所以这样命名,是因为 Java 的巨大成功(或者你喜欢的炒作)。之前被发明者 Netscape 称为 LiveScript(有人记得吗?)。
  • 你希望它在哪些浏览器上工作——这是你问题的最大变体。

标签: javascript jquery html css


【解决方案1】:

你可以用一些简单的 jQuery 来做到这一点:

http://jsfiddle.net/jpXjH/6/

var elementPosition = $('#navigation').offset();

$(window).scroll(function(){
        if($(window).scrollTop() > elementPosition.top){
              $('#navigation').css('position','fixed').css('top','0');
        } else {
            $('#navigation').css('position','static');
        }    
});

【讨论】:

  • 此外,并非所有浏览器都能正确呈现fixed CSS。所有现代浏览器都可以,但旧版浏览器(甚至诺基亚 N900 上的 Opera)不会那么好。
  • 更短的滚动回调:$('#navigation').css('position', ($(window).scrollTop()&gt;elementPosition.top) ? 'fixed' : 'relative');(并在你的 CSS 中设置 top:0) -- jsfiddle.net/mblase75/jpXjH/133
  • 这个解决方案在 2015 年仍然存在 IE 上的性能问题,您还有其他想法吗?
【解决方案2】:

我不会打扰 jQuery 或 LESS。在我看来,一个 javascript 框架是矫枉过正的。

window.addEventListener('scroll', function (evt) {

  // This value is your scroll distance from the top
  var distance_from_top = document.body.scrollTop;

  // The user has scrolled to the tippy top of the page. Set appropriate style.
  if (distance_from_top === 0) {

  }

  // The user has scrolled down the page.
  if(distance_from_top > 0) {

  }

});

【讨论】:

  • 但要获得广泛的浏览器兼容性,您还必须使用 attachEvent。
  • 问题不在于浏览器的兼容性。我试图保持相关性和易于理解。
  • 但如果您不使用 jQuery,您的答案并不完全正确。因为 jQuery 的一部分是处理兼容性问题。
  • “问题不在于浏览器兼容性。”
  • 我不是说你的答案是错误的。但是你可以通过添加一些兼容性代码来改进它。
【解决方案3】:

在实现这一点时存在一些问题,原始接受的答案没有回答:

  1. 窗口的onscroll 事件经常触发。这 意味着您要么必须使用非常高性能的侦听器,要么 你必须以某种方式延迟听众。 jQuery 创造者 John Resig 状态here如何 延迟机制可以实现,你应该这样做的原因 做。在我看来,鉴于当今的浏览器和环境,一个 高性能监听器也可以。 Here is an implementation of the pattern suggested by John Resig
  2. css 中 position:fixed 的工作方式,如果向下滚动页面并将元素从 position:static 移动到position: fixed,页面会“跳跃”一点,因为文档“松动”了元素的高度.您可以通过将高度添加到 scrollTop 并用另一个对象替换文档正文中丢失的高度来摆脱它。您还可以使用该对象来确定粘性项目是否已移动到 position: fixed 并减少对将 position: fixed 恢复到原始状态的代码的调用:Look at the fiddle here
  3. 现在,就性能而言,处理程序真正做的唯一代价高昂的事情是在每次调用时调用scrollTop。由于区间绑定处理程序也有其缺点,因此我将在这里争辩说,您可以将事件侦听器重新附加到原始滚动事件,以使其感觉更快捷而无需担心。但是,您必须在您定位/支持的每个浏览器上对其进行分析。 See it working here

代码如下:

JS

/* Initialize sticky outside the event listener as a cached selector.
 * Also, initialize any needed variables outside the listener for 
 * performance reasons - no variable instantiation is happening inside the listener.
 */
var sticky = $('#sticky'),
    stickyClone,
    stickyTop = sticky.offset().top,
    scrollTop,
    scrolled = false,
    $window = $(window);

/* Bind the scroll Event */
$window.on('scroll', function (e) {
    scrollTop = $window.scrollTop();

    if (scrollTop >= stickyTop && !stickyClone) {
        /* Attach a clone to replace the "missing" body height */
        stickyClone = sticky.clone().prop('id', sticky.prop('id') + '-clone')
        stickyClone = stickyClone.insertBefore(sticky);
        sticky.addClass('fixed');
    } else if (scrollTop < stickyTop && stickyClone) {
        /* Since sticky is in the viewport again, we can remove the clone and the class */
        stickyClone.remove();
        stickyClone = null;
        sticky.removeClass('fixed');
    }
});

CSS

body {
    margin: 0
}
.sticky {
    padding: 1em;
    background: black;
    color: white;
    width: 100%
}
.sticky.fixed {
    position: fixed;
    top: 0;
    left: 0;
}
.content {
    padding: 1em
}

HTML

<div class="container">
  <div id="page-above" class="content">
    <h2>Some Content above sticky</h2>
    ...some long text...
  </div>
  <div id="sticky" class="sticky">This is sticky</div>
  <div id="page-content" class="content">
    <h2>Some Random Page Content</h2>...some really long text...
  </div>
</div>

【讨论】:

  • 如果您在不跨越屏幕宽度的布局中使用它,则布局将在滚动时填充屏幕宽度。
【解决方案4】:

给你,没有框架,简短而简单:

var el = document.getElementById('elId');
var elTop = el.getBoundingClientRect().top - document.body.getBoundingClientRect().top;

window.addEventListener('scroll', function(){
    if (document.documentElement.scrollTop > elTop){
        el.style.position = 'fixed';
        el.style.top = '0px';
    }
    else
    {
        el.style.position = 'static';
        el.style.top = 'auto';
    }
});

【讨论】:

    【解决方案5】:

    您想使用jQuery WayPoints。这是一个非常简单的插件,完全符合您的描述。

    最直接的实现

        $('.thing').waypoint(function(direction) {
      alert('Top of thing hit top of viewport.');
    });
    

    您将需要设置一些自定义 CSS 来准确设置卡住的位置,这对于大多数方法来说都是正常的。

    This page 将向您展示您需要的所有示例和信息。

    为了将来参考,它停止和启动的示例是this website。这是一个“在野外”的例子。

    【讨论】:

      【解决方案6】:

      你可以去LESS CSS网站http://lesscss.org/

      他们的可停靠菜单很轻并且性能很好。唯一需要注意的是,效果发生在卷轴完成后。只需做一个查看源代码即可查看 js。

      【讨论】:

        【解决方案7】:

        你也可以用 css 做到这一点。

        只需使用position:fixed; 向下滚动时要修复的内容。

        你可以在这里举一些例子:

        http://davidwalsh.name/demo/css-fixed-position.php

        http://demo.tutorialzine.com/2010/06/microtut-how-css-position-works/demo.html

        【讨论】:

          【解决方案8】:
          window.addEventListener("scroll", function(evt) {
              var pos_top = document.body.scrollTop;   
              if(pos_top == 0){
                 $('#divID').css('position','fixed');
              }
          
              else if(pos_top > 0){
                 $('#divId').css('position','static');
              }
          });
          

          【讨论】:

            【解决方案9】:

            纯 Javascript 解决方案 (DEMO):

            <br/><br/><br/><br/><br/><br/><br/>
            <div>
              <div id="myyy_bar" style="background:red;"> Here is window </div>
            </div>
            <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
            
            
            <script type="text/javascript">
            var myyElement = document.getElementById("myyy_bar"); 
            var EnableConsoleLOGS = true;           //to check the results in Browser's Inspector(Console), whenever you are scrolling
            // ==============================================
            
            
            
            window.addEventListener('scroll', function (evt) {
                var Positionsss =  GetTopLeft ();  
                if (EnableConsoleLOGS) { console.log(Positionsss); }
                if (Positionsss.toppp  > 70)    { myyElement.style.position="relative"; myyElement.style.top = "0px";  myyElement.style.right = "auto"; }
                else                            { myyElement.style.position="fixed";    myyElement.style.top = "100px";         myyElement.style.right = "0px"; }
            });
            
            
            
            function GetOffset (object, offset) {
                if (!object) return;
                offset.x += object.offsetLeft;       offset.y += object.offsetTop;
                GetOffset (object.offsetParent, offset);
            }
            function GetScrolled (object, scrolled) {
                if (!object) return;
                scrolled.x += object.scrollLeft;    scrolled.y += object.scrollTop;
                if (object.tagName.toLowerCase () != "html") {          GetScrolled (object.parentNode, scrolled);        }
            }
            
            function GetTopLeft () {
                var offset = {x : 0, y : 0};        GetOffset (myyElement.parentNode, offset);
                var scrolled = {x : 0, y : 0};      GetScrolled (myyElement.parentNode.parentNode, scrolled);
                var posX = offset.x - scrolled.x;   var posY = offset.y - scrolled.y;
                return {lefttt: posX , toppp: posY };
            }
            // ==============================================
            </script>
            

            【讨论】:

            • 谢谢!您能否澄清一下 Positionsss.toppp > 70 检查的内容?图像和页面上边缘之间的空间?当我在具有不同内容量的页面上运行它时,它会提供不同的结果 - 对于具有大量内容的页面,图像跳得太快。尽管两个页面的标题大小相同。
            • 我见过可怕的变量名称,但我见过的最糟糕的是 Positionsss.toppp
            【解决方案10】:

            最近对我有用的解决方案是:

            .sticky {
              position: fixed;
              top: 0;
              width: 100%;
            }
            
            var header = document.getElementById("filters-tab");
            var sticky = header.offsetTop;
            
            if (window.pageYOffset > sticky) {
              header.classList.add("fixed");
            } else {
              header.classList.remove("fixed");
            }
            

            【讨论】:

              【解决方案11】:

              此操作不再需要 Javascript。 使用 CSS position:sticky 属性执行此操作

              https://css-tricks.com/position-sticky-2/

              【讨论】:

                猜你喜欢
                • 2022-10-14
                • 1970-01-01
                • 2019-01-13
                • 2020-05-09
                • 1970-01-01
                • 2012-03-12
                • 2018-12-28
                • 2011-10-21
                • 1970-01-01
                相关资源
                最近更新 更多