Programing

앵커 링크가 링크 된 위치보다 몇 픽셀 위로 이동하도록합니다.

lottogame 2020. 8. 18. 08:06
반응형

앵커 링크가 링크 된 위치보다 몇 픽셀 위로 이동하도록합니다.


이 질문을 요청 / 검색하는 가장 좋은 방법을 모르겠습니다.

앵커 링크를 클릭하면 페이지의 맨 위에 링크 된 영역이있는 페이지의 해당 섹션으로 이동합니다. 앵커 링크를 통해 페이지의 해당 부분으로 이동하고 싶지만 상단에 약간의 공간이 필요합니다. 에서와 마찬가지로 VERY TOP에서 연결된 부분으로 나를 보내지 않기를 원합니다. 100 픽셀 정도의 공간을 원합니다.

이게 말이 돼? 이게 가능해?

코드를 표시하도록 편집 됨-단지 앵커 태그 일뿐입니다.

<a href="#anchor">Click me!</a>

<p id="anchor">I should be 100px below where I currently am!</p>

window.addEventListener("hashchange", function () {
    window.scrollTo(window.scrollX, window.scrollY - 100);
});

이렇게하면 브라우저가 앵커로 점프하는 작업을 수행 할 수 있으며 해당 위치를 사용하여 오프셋 할 수 있습니다.

편집 1 :

@erb가 지적했듯이 이것은 해시가 변경되는 동안 페이지에있는 경우에만 작동합니다. #something이미 URL에 있는 페이지를 입력하면 위 코드에서 작동하지 않습니다. 이를 처리하는 또 다른 버전이 있습니다.

// The function actually applying the offset
function offsetAnchor() {
    if(location.hash.length !== 0) {
        window.scrollTo(window.scrollX, window.scrollY - 100);
    }
}

// This will capture hash changes while on the page
window.addEventListener("hashchange", offsetAnchor);

// This is here so that when you enter the page with a hash,
// it can provide the offset in that case too. Having a timeout
// seems necessary to allow the browser to jump to the anchor first.
window.setTimeout(offsetAnchor, 1); // The delay of 1 is arbitrary and may not always work right (although it did in my testing).

참고 : jQuery를 사용하려면, 당신은 단지 대체 할 수 window.addEventListener와 함께 $(window).on예이다. @Neon 감사합니다.

편집 2 :

몇몇 사람들이 지적했듯이 hashchange오프셋을 강제하는 이벤트 가 없기 때문에 동일한 앵커 링크를 연속으로 두 번 이상 클릭하면 위의 작업이 실패합니다 .

이 솔루션은 @Mave의 제안을 약간 수정 한 버전이며 단순성을 위해 jQuery 선택기를 사용합니다.

// The function actually applying the offset
function offsetAnchor() {
  if (location.hash.length !== 0) {
    window.scrollTo(window.scrollX, window.scrollY - 100);
  }
}

// Captures click events of all <a> elements with href starting with #
$(document).on('click', 'a[href^="#"]', function(event) {
  // Click events are captured before hashchanges. Timeout
  // causes offsetAnchor to be called after the page jump.
  window.setTimeout(function() {
    offsetAnchor();
  }, 0);
});

// Set the offset when entering page with hash present in the url
window.setTimeout(offsetAnchor, 0);

이 예제의 JSFiddle은 여기에 있습니다.


css로만 작업하면 고정 된 요소에 패딩을 추가 할 수 있습니다 (위의 솔루션에서와 같이) 불필요한 공백을 방지하려면 동일한 높이의 음수 여백을 추가 할 수 있습니다.

#anchor {
    padding-top: 50px;
    margin-top: -50px;
}

이것이 최선의 해결책인지 확실하지 않지만 잘 작동합니다.


더 나은 솔루션 :

<p style="position:relative;">
    <a name="anchor" style="position:absolute; top:-100px;"></a>
    I should be 100px below where I currently am!
</p>

<a>상대적으로 배치 된 개체 내부에 절대 위치로 태그를 배치하기 만하면 됩니다.

페이지에 들어갈 때 또는 페이지 내의 해시 변경을 통해 작동합니다.


최고의 솔루션

<span class="anchor" id="section1"></span>
<div class="section"></div>

<span class="anchor" id="section2"></span>
<div class="section"></div>

<span class="anchor" id="section3"></span>
<div class="section"></div>

<style>
.anchor{
  display: block;
  height: 115px; /*same height as header*/
  margin-top: -115px; /*same height as header*/
  visibility: hidden;
}
</style>

이것은 jQuery없이 및 페이지로드시 작동합니다.

(function() {
    if (document.location.hash) {
        setTimeout(function() {
            window.scrollTo(window.scrollX, window.scrollY - 100);
        }, 10);
    }
})();

요소에 링크 한 다음 순수한 CSS를 사용하여 해당 요소를 페이지 상단에서 임의의 거리에 '위치'하려면을 사용해야 padding-top합니다. 이렇게하면 요소가 여전히 창 상단에 배치됩니다. 뷰포트 상단에서 약간 떨어진 위치에 표시됩니다 . 예를 들면 다음과 같습니다.

<a href="#link1">Link one</a>
<a href="#link2">Link two</a>

<div id="link1">
    The first.
</div>

<div id="link2">
    The second.
</div>

CSS :

div {
    /* just to force height, and window-scrolling to get to the elements.
       Irrelevant to the demo, really */
    margin-top: 1000px;
    height: 1000px;
}

#link2 {
    /* places the contents of the element 100px from the top of the view-port */
    padding-top: 100px;
}

JS Fiddle 데모 .

일반 JavaScript 접근 방식을 사용하려면 :

function addMargin() {
    window.scrollTo(0, window.pageYOffset - 100);
}

window.addEventListener('hashchange', addMargin);

JS Fiddle 데모 .


다음과 같은 명시 적 앵커 이름을 사용하는 경우

<a name="sectionLink"></a>
<h1>Section<h1>

그런 다음 CSS에서 간단히 설정할 수 있습니다.

A[name] {
    padding-top:100px;
}

이것은 HREF 앵커 태그가 NAME 속성도 지정하지 않는 한 작동합니다.


이것은 작동합니다.

    $(document).ready(function () {
    $('a').on('click', function (e) {
        // e.preventDefault();

        var target = this.hash,
            $target = $(target);

       $('html, body').stop().animate({
        'scrollTop': $target.offset().top-49
    }, 900, 'swing', function () {
    });

        console.log(window.location);

        return false;
    });
});

.top-49를 앵커 링크에 맞는 것으로 변경하십시오.


Eric의 대답은 훌륭하지만 실제로는 시간 초과가 필요하지 않습니다. jQuery를 사용하는 경우 페이지가로드 될 때까지 기다릴 수 있습니다. 따라서 코드를 다음과 같이 변경하는 것이 좋습니다.

// The function actually applying the offset
function offsetAnchor() {
    if (location.hash.length !== 0) {
        window.scrollTo(window.scrollX, window.scrollY - 100);
    }
}

// This will capture hash changes while on the page
$(window).on("hashchange", function () {
    offsetAnchor();
});

// Let the page finish loading.
$(document).ready(function() {
    offsetAnchor();
});

이것은 또한 우리가 임의의 요소를 제거합니다.


이 코드를 시도하면 링크를 클릭했을 때 이미 부드러운 애니메이션이 있습니다.

$(document).on('click', 'a[href^="#"]', function (event) {
    event.preventDefault();

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top - 100
    }, 500);
});

가장 쉬운 해결책 :

CSS

#link {
    top:-120px; /* -(some pixels above) */
    position:relative;
    z-index:5;
}

HTML

<body>
    <a href="#link">Link</a>
    <div>
        <div id="link"></div> /*this div should placed inside a target div in the page*/
        text
        text
        text
    <div>
</body>

Thomas의 솔루션 변형 : CSS element> element selectors 는 여기에서 편리 할 수 ​​있습니다.

CSS

.paddedAnchor{
  position: relative;
}
.paddedAnchor > a{
  position: absolute;
  top: -100px;
}

HTML

<a href="#myAnchor">Click Me!</a>

<span class="paddedAnchor"><a name="myAnchor"></a></span>

링크를 클릭하면 클래스가있는 요소가 위치 할 때마다 스크롤 위치가 100px 위로 이동합니다 paddedAnchor.

IE가 아닌 브라우저 및 버전 9의 IE에서 지원됩니다. IE 7 및 8에서 지원 <!DOCTYPE>하려면 a 를 선언해야합니다.


나는 나 자신을위한 쉬운 해결책을 찾았습니다. 여백 상단이 15px입니다.

HTML

<h2 id="Anchor">Anchor</h2>

CSS

h2{margin-top:-60px; padding-top:75px;}

나는 이것이 조금 늦었다는 것을 알고 있지만 Bootstrap의 Scrollspy를 사용하는 경우 코드에 넣을 매우 중요한 것을 발견했습니다. ( http://getbootstrap.com/javascript/#scrollspy )

이것은 나를 몇 시간 동안 미치게 만들었다.

The offset for scroll spy MUST match the window.scrollY or else you'll run the risk of:

  1. Getting a weird flicker effect when scrolling
  2. Youll find that when you click on anchors, youll land in that section, but scroll spy will assume you are a section above it.

 var body = $('body');
    body.scrollspy({
        'target': '#nav',
        'offset': 100 //this must match the window.scrollY below or you'll have a bad time mmkay
});

$(window).on("hashchange", function () {
        window.scrollTo(window.scrollX, window.scrollY - 100);
});


Based on @Eric Olson solution just modify a little to include the anchor element that I want to go specifically

// Function that actually set offset
function offsetAnchor(e) {
    // location.hash.length different to 0 to ignore empty anchor (domain.me/page#)
    if (location.hash.length !== 0) {
        // Get the Y position of the element you want to go and place an offset
        window.scrollTo(0, $(e.target.hash).position().top - 150);
    }
}

// Catch the event with a time out to perform the offset function properly
$(document).on('click', 'a[href^="#"]', function (e) {
    window.setTimeout(function () {
        // Send event to get the target id later
        offsetAnchor(e);
    }, 10);
});

I just have the same problem. I have a nav posited pixed and i want the angkor to start under the nav. The solution of window.addEventListener... not work for me because i set my page to be scroll-behavior:smooth so it set the offset instead scroll to the angkor. the setTimeout() work if the time is anough for scroll to the end but it still not looking good. so my solution was to add a posited absolute div in the angkor, with height:[the height of the nav] and bottom:100%. in this case this div ended in the top of the angkor element, and start at the position where you what the angkor to scroll to. now all what i do is set the angkor link to this absolute div and the wor done :)

html,body{
    margin:0;
    padding:0;
    scroll-behavior:smooth;
}

nav {
    height:30px;
    width:100%;
    font-size:20pt;
    text-align:center;
    color:white;
    background-color:black;
    position:relative;
}

#my_nav{
    position:fixed;
    z-index:3;
}
#fixer_nav{
    position:static;
}

#angkor{
    position:absolute;
    bottom:100%;
    height:30px;
}
<nav id="my_nav"><a href="#angkor">fixed position nav<a/></nav>
<nav id="fixer_nav"></nav>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.
</p>

<nav><div id="angkor"></div>The angkor</nav>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.

</p>


i was facing the similar issue and i resolved by using following code

$(document).on('click', 'a.page-scroll', function(event) {
        var $anchor = $(this);
        var desiredHeight = $(window).height() - 577;
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top - desiredHeight
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });

Using only css and having no problems with covered and unclickable content before (the point of this is the pointer-events:none):

CSS

.anchored::before {
    content: '';
    display: block;
    position: relative;
    width: 0;
    height: 100px;
    margin-top: -100px;
}

HTML

<a href="#anchor">Click me!</a>
<div style="pointer-events:none;">
<p id="anchor" class="anchored">I should be 100px below where I currently am!</p>
</div>

<a href="#anchor">Click me!</a>

<div style="margin-top: -100px; padding-top: 100px;" id="anchor"></div>
<p>I should be 100px below where I currently am!</p>

참고URL : https://stackoverflow.com/questions/17534661/make-anchor-link-go-some-pixels-above-where-its-linked-to

반응형