Scroll to Pin

Ich habe ein einfaches und kleines Script geschrieben, welches Elemente an einer Position fest pint. Wie das funktioniert könnt ihr euch in der Linken Spalte ansehen. Der Trigger - "scrollpin-trigger" gibt an welcher scroll Position sich das zu fixierende Element grade befindet. Über den Wrapper - "scrollpin-section" wird die Dauer und Position des zu Pinenden Elementes bestimmt, da das Element über css die Position fixed bekommt, müssen auch nich zusätzliche Werte gesetzt werden (left und width). Über "pinTopPosition" kann man nun bestimmen ab wo das Element fixiert werden soll.

Der HTML Code

<div class="scrollpin">
    <section class="scrollpin-section" style="height: 120vh">
        <div class="scrollpin-trigger"></div>
        <div class="scrollpin-item js-calendar-pin">
            <span class="scrollpin-item-month">Dezember</span>
            <span class="scrollpin-item-day">01</span>
        </div>
    </section>
</div>


Der CSS Code

.scrollpin div {
    box-sizing: border-box;
}

.scrollpin-section{
    position: relative;
    border: 1px solid #000;
    width: 100%;
}

.scrollpin-section + .scrollpin-section{
    border-top: 0;
}

.scrollpin-item{
    position: absolute;
    left: 0;
    width: 100%;
    text-align: center;
    background-color: #ccc;
}

.scrollpin-item-month{
    font-size: 30px;
    line-height: 1;
    text-transform: uppercase;
    display: block;
}

.scrollpin-item-day{
    display: block;
    font-size: 100px;
    line-height: 1;
}


Und der der jQuery Code

if($(".js-calendar-pin").length){

    function scrollToPin(scrollY){
        var pinTopPosition = 0;

        $(".js-calendar-pin").each(function(){

        var el = $(this),
            elHeight = el.outerHeight(true),
            wrapper = el.closest(".scrollpin-section"),
            triggerOffset = wrapper.find(".scrollpin-trigger").offset().top - pinTopPosition,
            wrapperOffset = wrapper.offset().top - pinTopPosition,
            wrapperOffsetBottom = wrapperOffset + wrapper.height();

            if(triggerOffset < scrollY){
                if(wrapperOffsetBottom - elHeight > scrollY){
                    //pin start
                    el.removeClass("uppin").addClass("pin");
                    el.css({
                        'position': 'fixed',
                        'top': Math.abs(pinTopPosition),
                        'left': wrapper[0].getBoundingClientRect().left + 1, //1px border left
                        'bottom': '',
                        'width': wrapper[0].getBoundingClientRect().width - 2, //-2px border left and right
                    });
                }else{
                    //pin end
                    el.removeClass("pin").addClass("uppin");
                    el.css({
                        'position': '',
                        'top': '',
                        'left': '',
                        'bottom': '0',
                        'width': '',
                    });
                }
            }else{
                //pin reset
                el.removeClass("pin uppin");
                el.css({
                    'position': '',
                    'top': '',
                    'left': '',
                    'bottom': '',
                    'width': '',
                });
            }
        });
    }

    $(window).on("scroll", function(){
        scrollToPin($(window).scrollTop());
    });

    $(window).on("resize", function(){
        scrollToPin($(window).scrollTop());
    });
}
Dezember 01
Dezember 02
Dezember 03
Dezember 04
Dezember 05