programing

vue.js에 고정된 헤더가 있는 스틱 사이드바(jQuery 없음)

newsource 2022. 8. 8. 20:37

vue.js에 고정된 헤더가 있는 스틱 사이드바(jQuery 없음)

Make position: sticky와 같은 고정 동작(Vue2의 경우)에 대한 이 질문에 대한 답변에 이어 응용 프로그램에 구현하려고 했습니다.

솔루션이 약간 버그가 있어서(특히 다른 탭을 열고 돌아왔을 때) jQuery를 사용하여 구현하기로 결정했고 예상대로 작동합니다.

다음으로 작업 예를 제시하겠습니다.

<template>
    <div>
        <div class="recap">
            <div class="inner" :style="recapStyle">
            </div>
        </div>
    </div>
</template>
<script>
export default {
    name: 'ProductRecap',
    data() {
        return {
            scrollY: null,
            top: null,
            bottom: null,
            marginTop: 40,
            recapStyle: {},
        };
    },
    methods: {
        updatePosition(scroll) {
            // using jQuery to calculate amount
            const offset = $(this.$el).offset().top;
            const scrollAmount = offset - scroll;
            const rectHeight = $(this.$el).find('.inner').outerHeight();
            if (scrollAmount < this.top) {
                let updatedTop = scroll - offset + this.top;
                if ((scroll + rectHeight) < this.bottom) {
                    this.prevScroll = updatedTop;
                } else {
                    updatedTop = this.prevScroll;
                }
                this.$set(this.recapStyle, 'top', `${updatedTop}px`);
            } else {
                this.$delete(this.recapStyle, 'top');
            }
        },
    },
    watch: {
        scrollY(scrollUpdate) {
            // call `updatePosition` on scroll
            this.updatePosition(scrollUpdate);
        },
    },
    mounted() {
        // calculate header size (position: fixed) and add a fixed offset
        this.top = $('#main-header').outerHeight() + this.marginTop;
        // calculate height of the document (without the footer)
        this.bottom = document.querySelector('.global-container').offsetHeight;
        // update scrollY position
        window.addEventListener('scroll', _.throttle(() => {
            this.scrollY = Math.round(window.scrollY);
        }, 20, { leading: true }));
    },
};
</script>

단, 오프셋 계산에 jQuery를 사용하지 않는 솔루션을 찾고 싶기 때문에 "You Might Not Need jQuery"로 이동했습니다만, 이 경우,offset아직 버그가 좀 심하다는 제안과 헤어지세요.

$(el).offset();

다음과 같이 됩니다.

var rect = el.getBoundingClientRect();

{
  top: rect.top + document.body.scrollTop,
  left: rect.left + document.body.scrollLeft
}

그래서 나는 줄을 바꿨다.

const offset = $(this.$el).offset().top;

포함:

const rect = this.$el.getBoundingClientRect();
const offset = rect.top + document.body.scrollTop;

그러나 고정된 머리글과 사이드바의 거리는 스크롤에 따라 늘어납니다.누구라도 어떻게 고쳐야 하는지 설명해 주실 수 있나요?

동작하는 바이올린을 다음에 나타냅니다(약간 단순화).만지작거리다

간단한 답변은 다음 두 행을 사용하는 것입니다(첫 번째 행은 사용자의 것입니다).

  const rect = this.$el.getBoundingClientRect();
  const offset = rect.top + window.pageYOffset;

물론 더 긴 답변에는 이 결과를 얻기 위한 사고 과정이 포함됩니다.나는 달렸다

  console.log($(this.$el).offset + "");

해당하는 장소에서 바이올린을 켜서 오프셋 기능이 어떻게 구현되어 있는지 확인하고 다음 정보를 얻습니다.

function( options ) {

        // Preserve chaining for setter
        if ( arguments.length ) {
            return options === undefined ?
                this :
                this.each( function( i ) {
                    jQuery.offset.setOffset( this, options, i );
                } );
        }

        var rect, win,
            elem = this[ 0 ];

        if ( !elem ) {
            return;
        }

        // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
        // Support: IE <=11+
        // Running getBoundingClientRect on a
        // disconnected node in IE throws an error
        if ( !elem.getClientRects().length ) {
            return { top: 0, left: 0 };
        }

        // Get document-relative position by adding viewport scroll to viewport-relative gBCR
        rect = elem.getBoundingClientRect();
        win = elem.ownerDocument.defaultView;
        return {
            top: rect.top + win.pageYOffset,
            left: rect.left + win.pageXOffset
        };
    }

이 솔루션은 다음 라인에서 영감을 얻습니다.

            top: rect.top + win.pageYOffset,

언급URL : https://stackoverflow.com/questions/57463159/sticky-sidebar-with-fixed-header-in-vue-js-without-jquery