Замена липкого заголовка вторым заголовком, когда он достигает текущего застрявшего заголовка

0

Я читал на липких заголовках, и это то, что я нашел до сих пор. Первый липкий заголовок отлично работает, но как я могу прокрутить первый заголовок и сделать второй заголовок, когда он выталкивает первый заголовок вне поля зрения, когда он встречает его?

http://jsfiddle.net/

<style>
  body {
    margin: 0;
    text-align: center;
    font-family: sans-serif;
  }
  .fixed {
    position: fixed;
    top: 0;
  }
  .sticky {
    width: 100%;
    background: #F6D565;
    padding: 25px 0;
    text-transform: uppercase;
  }
</style>

<p style="margin-bottom:100px;">Scroll this page.</p>
<div class="sticky"><h3>Super amazing header</h3></div>
<p style="margin-top:500px;">Still there?</p>
<p style="margin-top:500px;">Yep!</p>
<p style="margin-top:500px;">Scroll so hard!</p>
<div class="sticky"><h3>Super amazing 123</h3></div>
<p style="margin-top:500px;">Still there?</p>
<p style="margin-top:500px;">Yep!</p>
<p style="margin-top:500px;">Scroll so hard!</p>
<script>
var sticky = document.querySelector('.sticky');
var origOffsetY = sticky.offsetTop;

function onScroll(e) {
  window.scrollY >= origOffsetY ? sticky.classList.add('fixed') :
                                  sticky.classList.remove('fixed');
}

document.addEventListener('scroll', onScroll);
</script>

2 ответа

5
Лучший ответ

Я считаю, что следующее будет делать именно так, как вы хотите...

#firstHeader будет привязываться к вершине, когда прокручивается мимо, а затем, когда #secondHeader сталкивается с нижней частью #firstHheader они присоединятся, и #firstHeader будет оттолкнут от экрана, пока #secondHeader достигнет вершины экрана и связывается там...

Надеюсь, это имеет смысл, если нет, возможно, будет легче, если вы увидите это в действии: http://jsfiddle.net/yZKea/

Это решение использует jquery. Поэтому вам нужно включить ссылку на нее в head перед остальной частью JS кода:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

ПРИМЕЧАНИЕ. JS не такой сложный или до тех пор, пока он выглядит, в большинстве случаев это повторяющаяся настройка стилей. Вы можете легко изменить его на несколько строк :)

CSS

html, body {
    margin: 0;
    padding: 0;
    border: 0;
}
.spacer{
    height:200px;
    background:#f00;
    opacity:.5;
    border-top:#d22 5px solid;
    width: 100%;
}
#firstHeader{
    background:#00f;
    height: 100px;
    width: 100%;
    z-index:500;
}
#secondHeader{
    background:#0f0;
    height: 100px;
    width: 100%;
    z-index:500;
}

HTML

<body>
    <div class="spacer"></div>
    <div id="firstHeader">Header 1</div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div id="secondHeader">Header 2</div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
    <div class="spacer"></div>
</body>

JS

function scrollFunction(){
    var sticky1 = $('#firstHeader');
    var sticky2 = $('#secondHeader');

    sticky1.css({
        position: "static",
        top: 0
    });
    sticky2.css({
        position: "static",
        top: 0
    });
    $('body').css({
        "padding-top": 0
    });

    var topOffset1 = sticky1.offset().top;
    var topOffset2 = sticky2.offset().top;

    var stickyHeight1 = sticky1.outerHeight();
    var stickyHeight2 = sticky2.outerHeight();

    var scrollHeight = $(window).scrollTop();

    if(topOffset1 <= scrollHeight && scrollHeight < topOffset2 - stickyHeight1){
        sticky1.css({
            position: "fixed",
            top: 0
        });
        sticky2.css({
            position: "static",
            top: 0
        });
        $('body').css({
            "padding-top": stickyHeight1
        });
    }
    else if(scrollHeight >= topOffset2 - stickyHeight1 && scrollHeight < topOffset2){
        sticky1.css({
            position: "fixed",
            top: - (scrollHeight - (topOffset2 - stickyHeight1))
        });
         sticky2.css({
            position: "fixed",
            top: stickyHeight1 - (scrollHeight - (topOffset2 - stickyHeight1))
        });
        $('body').css({
            "padding-top": stickyHeight1 + stickyHeight2
        });
    }
    else if(scrollHeight >=  topOffset2){
        sticky1.css({
            position: "static"
        });
         sticky2.css({
            position: "fixed",
            top: 0
        });
        $('body').css({
            "padding-top": stickyHeight2
        });
    }
    else{
        sticky1.css({
            position: "static",
            top: 0
        });
        sticky2.css({
            position: "static",
            top: 0
        });
        $('body').css({
            "padding-top": 0
        });
    }

}

$(window).scroll(scrollFunction);

Обновленный JS

Это должно решить проблему с наличием экрана мерцания.

var topOffset1, topOffset2;

function scrollFunction(){

    var sticky1 = $('#firstHeader');
    var sticky2 = $('#secondHeader');

    var stickyHeight1 = sticky1.outerHeight();
    var stickyHeight2 = sticky2.outerHeight();

    var scrollHeight = $(window).scrollTop();

    if(topOffset1 <= scrollHeight && scrollHeight < topOffset2 - stickyHeight1){
        sticky1.css({
            position: "fixed",
            top: 0
        });
        sticky2.css({
            position: "static",
            top: 0
        });
        $('body').css({
            "padding-top": stickyHeight1
        });
    }
    else if(scrollHeight >= topOffset2 - stickyHeight1 && scrollHeight < topOffset2){
        sticky1.css({
            position: "fixed",
            top: - (scrollHeight - (topOffset2 - stickyHeight1))
        });
         sticky2.css({
            position: "fixed",
            top: stickyHeight1 - (scrollHeight - (topOffset2 - stickyHeight1))
        });
        $('body').css({
            "padding-top": stickyHeight1 + stickyHeight2
        });
    }
    else if(scrollHeight >=  topOffset2){
        sticky1.css({
            position: "static"
        });
         sticky2.css({
            position: "fixed",
            top: 0
        });
        $('body').css({
            "padding-top": stickyHeight2
        });
    }
    else{
        sticky1.css({
            position: "static",
            top: 0
        });
        sticky2.css({
            position: "static",
            top: 0
        });
        $('body').css({
            "padding-top": 0
        });
    }

}

$(function(){
    topOffset1 = $('#firstHeader').offset().top;
    topOffset2 = $('#secondHeader').offset().top;
});

$(window).scroll(scrollFunction);

JS Для переменного количества заголовков

Просто добавьте класс .header в свои заголовки, и это будет работать для любого количества заголовков (1, 5, 100... Вы понимаете).

Это полная замена вышеупомянутого JS, и каждый новый заголовок будет вытеснять старый заголовок экрана до того, как он привяжется к вершине.

См. Этот обновленный jsfiddle для примера в действии: http://jsfiddle.net/5bkst/

var topOffset = new Array();

function scrollFunction(){

    var scrollHeight = $(window).scrollTop();
    var headerCounter = 0;
    var scrolled      = 0;
    var headerItems   = $('.header').length;

    $('.header').each(function(index, el){

        var elementHeight = $(this).outerHeight();

        var nextElementHeight = 0;
        var nextElement;

        if(index !== $('.header').length - 1){
            nextElementHeight = $('.header').eq(index + 1).outerHeight();
            nextElement       = $('.header').eq(index + 1);
        }

        if(scrollHeight >= topOffset[headerCounter]
            && (scrollHeight < topOffset[headerCounter + 1] || headerCounter == headerItems-1)){

            scrolled = 1;

            if(scrollHeight >= topOffset[headerCounter + 1] - elementHeight){
                $(this).css({
                    position: "fixed",
                    top: - (scrollHeight - (topOffset[headerCounter + 1] - elementHeight))
                });
                nextElement.css({
                    position: "fixed",
                    top: topOffset[headerCounter + 1] - scrollHeight
                });
                $('body').css({
                    "padding-top": elementHeight + nextElementHeight
                });
                return false;
            }
            else{
                $(this).css({
                    position: "fixed",
                    top: 0
                });
                nextElement.css({
                    position: "static",
                });
                $('body').css({
                    "padding-top": elementHeight
                });
            }

        }
        else{
            $(this).css({
                position: "static"
            });
        }

        headerCounter++;
    });

    if(scrolled == 0){
        $('body').css({
            "padding-top": 0
        });
    }
}

$(function(){
    $('.header').each(function(){
        topOffset.push($(this).offset().top);
    });
});

$(window).scroll(scrollFunction);
  • 0
    Да, это работает, но почему мой экран мерцает, как сумасшедший, когда я вижу его в действии?
  • 0
    Возможно, потому, что он устанавливает все элементы в static (то есть без закрепленных заголовков) для вычисления некоторых переменных в начале вызова функции. Это не должно быть заметно, если, может быть, вы находитесь на старой машине? Я все равно посмотрю на код
Показать ещё 4 комментария
1

Если вы хотите переключить заголовки, чем попробовать это. FIDDLE

<header class="default">
  <div class="default-cnt">
    Default Content
  </div>
  <div class="fixed-cnt">
    Fixed Content
  </div>
</header>

header {
  width: 100%;
  height: 120px;
  padding: 10px;
  letter-spacing: 1px;
}
.default {
  background: #555;
  position: relative;
  color: #fff;
}
.fixed {
  background: #01a8e7;
  position: fixed;
  top: 0;
  left: 0;
  color: #000;
}
.default .fixed-cnt {
  display: none;
}
.fixed .default-cnt {
display: none;
}

$(function() {
  var header = $('header');
  var headOff = header.offset();

  $(window).scroll(function() {
    if($(this).scrollTop() > 120 + headOff.top && header.hasClass('default')) {
      header.fadeOut('fast', function() {
        $(this).removeClass('default').addClass('fixed').fadeIn('fast');
      });
    } 
    else if($(this).scrollTop() <= 120 + header.height() && header.hasClass('fixed')) {
      header.fadeOut('fast', function() {
        $(this).removeClass('fixed').addClass('default').fadeIn('fast');
      });
    }
  });
});

Ещё вопросы

Сообщество Overcoder
Наверх
Меню