JavaScript를 트리거하는 링크를 클릭 할 때 웹 페이지가 맨 위로 스크롤되지 않도록하려면 어떻게합니까?


135

다음과 같은 jQuery 또는 JavaScript 이벤트와 연결된 링크가있는 경우 :

<a href="#">My Link</a>

페이지가 맨 위로 스크롤되지 않도록하려면 어떻게합니까? 앵커에서 href 속성을 제거하면 페이지가 맨 위로 스크롤되지 않지만 링크를 클릭 할 수있는 것처럼 보이지 않습니다.

답변:


197

클릭 이벤트에 대한 기본 동작 (예 : 링크 대상으로 이동)이 발생하지 않도록해야합니다.

이를 수행하는 두 가지 방법이 있습니다.

옵션 1: event.preventDefault()

.preventDefault()핸들러로 전달 된 이벤트 오브젝트 의 메소드를 호출하십시오 . jQuery를 사용하여 핸들러를 바인딩하는 경우 해당 이벤트는의 인스턴스이며 jQuery.Event의 jQuery 버전이 .preventDefault()됩니다. addEventListener핸들러를 바인딩 하는 데 사용 하는 경우 Event및의 원시 DOM 버전이 .preventDefault()됩니다. 어느 쪽이든 당신이 원하는 것을 할 것입니다.

예 :

$('#ma_link').click(function($e) {
    $e.preventDefault();
    doSomething();
});

document.getElementById('#ma_link').addEventListener('click', function (e) {
    e.preventDefault();
    doSomething();
})

옵션 2 : return false;

jQuery에서 :

이벤트 핸들러에서 false를 반환하면 자동으로 event.stopPropagation () 및 event.preventDefault ()가 호출됩니다.

따라서 jQuery를 사용하면이 방법을 사용하여 기본 링크 동작을 방지 할 수 있습니다.

$('#ma_link').click(function(e) {
     doSomething();
     return false;
});

원시 DOM 이벤트를 사용하는 경우 HTML 5 사양에 따라 이러한 동작이 적용되므로 최신 브라우저에서도 작동합니다. 그러나 이전 버전의 사양은 그렇지 않았으므로 이전 브라우저와의 최대 호환성이 필요한 경우 .preventDefault()명시 적으로 호출해야합니다 . 사양에 대한 자세한 내용은 event.preventDefault () 대 false 반환 (jQuery 없음)을 참조하십시오 .


9
: 클릭 처리기를 부착 필요로하지 않는 솔루션 (3 년 후반) 게시 stackoverflow.com/a/11246131/216941
매트 Crinklaw - 보그

이 경우 Achilles는 링크를 클릭 가능한 것으로 표시하기 위해 href = "#"을 사용할 필요가 없기 때문에이 작업을 수행합니다. 자세한 내용은 내 답변을 참조하십시오.
achecopar

164

#!대신 href를 설정할 수 있습니다#

예를 들어

<a href="#!">Link</a>

클릭하면 스크롤되지 않습니다.

조심해! 클릭하면 브라우저 기록에 항목이 계속 추가됩니다. 즉, 링크를 클릭하면 사용자의 뒤로 버튼이 이전 페이지로 이동하지 않습니다. 따라서 .preventDefault()접근 방식을 사용하거나 두 가지를 함께 사용하는 것이 좋습니다 .

여기에 이것을 보여주는 Fiddle이 있습니다 (스크롤 바가 나타날 때까지 브라우저를 아래로 긁으십시오) :
http://jsfiddle.net/9dEG7/


사양 대단원-왜 이것이 작동하는지 :

이 동작은 조각 식별자 탐색 섹션 의 HTML5 사양에 지정되어 있습니다. href가있는 링크로 "#"인해 문서가 맨 위로 스크롤 되는 이유 는이 동작이 빈 조각 식별자를 처리하는 방법으로 명시 적으로 지정 되었기 때문입니다.

2. fragid빈 문자열 인 경우 문서의 표시된 부분이 문서의 상단입니다

"#!"대신 href를 사용하면이 규칙을 피할 수 있기 때문에 간단하게 작동합니다. 느낌표에 대해 아무것도 마법이있다 - 그것은 이제까지 일치에 띄게 전형적인 fragid에 다른과 가능성이 있기 때문에 그냥 편리한 조각 식별자를하게 id하거나 name페이지에 요소의. 실제로 해시 뒤에는 거의 모든 것을 넣을 수 있습니다. 충분하지 않은 유일한 취약성은 빈 문자열, 단어 'top'또는 페이지의 요소 속성 name또는 일치하는 문자열입니다 id.

더 정확하게는, 우리는 조각화 에서 문서표시된 부분 을 결정하기 위해 다음 알고리즘의 8 단계로 넘어갈 수있는 조각 식별자가 필요합니다 .

  1. URL 파서 알고리즘을 URL에 적용하고 fragid를 결과 구문 분석 된 URL의 조각 구성 요소로 둡니다 .

  2. 경우 fragid빈 문자열은 다음 문서의 표시된 부분은 문서의 맨입니다; 여기서 알고리즘을 중지하십시오.

  3. 하자 fragid bytes%의 디코딩의 결과 fragid.

  4. decoded fragidUTF-8 디코더 알고리즘을 적용한 결과를 보자 fragid bytes. UTF-8 디코더에서 디코더 오류가 발생하면 디코더를 중단하고 대신 레이블이 지정된 단계로 이동하십시오 no decoded fragid.

  5. DOM에 정확히 동일한 ID를 가진 decoded fragid요소가있는 경우 트리 순서의 첫 번째 요소는 문서의 표시된 부분입니다. 여기서 알고리즘을 중지하십시오.

  6. 해독 된 fragid 없음 : DOM에 이름 속성이 있고 fragid( 와 같지 않은decoded fragid ) 이름 속성을 가진 요소가있는 경우 트리 순서의 첫 번째 요소는 문서의 표시된 부분입니다. 여기서 알고리즘을 중지하십시오.

  7. 경우 fragid는 문자열에 대한 ASCII의 대소 문자를 구분하지 일치는 top다음 문서의 표시된 부분은 문서의 맨입니다; 여기서 알고리즘을 중지하십시오.

  8. 그렇지 않으면 문서에 표시된 부분이 없습니다.

8 단계를 밟고 문서에 표시된 부분이 없으면 다음 규칙이 적용됩니다.

표시된 부분이 없으면 사용자 에이전트는 아무 작업도 수행하지 않아야합니다.

브라우저가 스크롤되지 않는 이유입니다.


4
'!'를 넣더라도 상관 없습니다. id가 DOM의 일부가 아닌 한 다른 값.
Gopinath

3
한 번이 방법을 옹호 한 후, 나는 180을 해왔으며 이에 대해 조언했습니다. 주의 : 이와 같은 링크는 여전히 페이지 URL을 변경하여 브라우저 기록에 추가 항목을 생성하고 "뒤로"버튼으로 인해 사용자가 기대하는 것을 수행하는 대신 URL에서 단편을 간단히 제거합니다. 따라서이 솔루션 자체는 요청에 따라 질문에 대답하는 반면 일반적으로 preventDefault()클릭 핸들러에서 사용 하는 대신에 슬프게도 바람직한 대안이 아닙니다 .
Mark Amery

1
href = "javascript :;"를 사용하지 않는 이유 대신? 내가 아는 한 브라우저의 기록은 변경되지 않습니다. 내 답변에 게시했습니다.
achecopar

30

쉬운 접근 방식은이 코드를 활용하는 것입니다.

<a href="javascript:void(0);">Link Title</a>

이 방법으로 페이지를 새로 고치지 않아도되므로 스크롤 막대가 그대로 유지됩니다. 또한 프로그래밍 방식으로 onclick 이벤트를 변경하고 jQuery를 사용하여 클라이언트 측 이벤트 바인딩을 처리 할 수 ​​있습니다.

이러한 이유로 위의 솔루션이 다음보다 낫습니다.

<a href="javascript:myClickHandler();">Link Title</a>
<a href="#" onclick="myClickHandler(); return false;">Link Title</a>

myClickHandler 메소드가 실패하지 않는 경우에만 마지막 솔루션으로 스크롤 점프 문제를 피할 수 있습니다.


12

호출하는 코드에서 false를 반환하면 효과가 있으며 여러 상황에서 선호되는 방법이지만 다음과 같이 할 수도 있습니다.

<a href="javascript:;">Link Title</a>

SEO에 관해서는 실제로 링크가 사용될 대상에 달려 있습니다. 실제로 다른 콘텐츠에 연결하기 위해 그것을 사용하려는 경우 이상적으로는 여기에서 의미있는 것을 원한다고 동의하지만 기능 목적으로 링크를 사용하는 경우 스택 오버플로가 포스트 툴바 (굵게, 기울임 꼴, 하이퍼 링크)와 같은 것일 수 있습니다 등) 상관 없습니다.


9

당신은 변경해야합니다

<a href="#">My Link</a>

<a href="javascript:;">My Link</a>

이 방법으로 링크를 클릭하면 페이지가 맨 위로 스크롤되지 않습니다. href = "#"를 사용하고 기본 이벤트가 실행되는 것을 방지하는 것보다 깨끗합니다.

나는에 대한 첫 번째 대답에이 좋은 이유가 이 질문에 (가)와 같이 return false;호출 된 함수에서 오류가 발생하면 실행되지 않습니다, 또는 당신이 추가 할 수 있습니다 return false;A와 doSomething()기능 그리고 사용하는 것을 잊지return doSomething();



4

단순히 href값을 변경할 수 있다면 다음 을 사용해야합니다.

<a href="javascript:void(0);">Link Title</a>

방금 제기 한 또 다른 깔끔한 솔루션은 jQuery를 사용하여 클릭 동작이 발생하지 않고 페이지가 스크롤되도록하지만 href="#"링크에 대해서만 스크롤하는 것 입니다.

<script type="text/javascript">
    /* Stop page jumping when links are pressed */
    $('a[href="#"]').live("click", function(e) {
         return false; // prevent default click action from happening!
         e.preventDefault(); // same thing as above
    });
</script>

반드시 줄 return false뒤에 있어야합니다 preventDefault(). 그렇지 않으면이 두 번째 줄에 도달하지 못할 것입니까?
hobailey

3

처음에는 페이지 상단보다 더 합리적인 것으로 연결하십시오. 그런 다음 기본 이벤트를 취소하십시오.

실용적인 점진적 향상 의 규칙 2를 참조하십시오 .


또한 사이트를보다 SEO 친화적으로 만들 수 있습니다.
Frankie

2

또한 onclick 속성 내에서 event.preventDefault 를 사용할 수 있습니다 .

<a href="#" onclick="event.preventDefault(); doSmth();">doSmth</a>

엑스트라 클릭 이벤트를 작성할 필요가 없습니다.


0

다음과 같이 간단히 쓸 수도 있습니다.

<a href="#!" onclick="function()">Delete User</a>

0

함수를 호출 할 때 return false 예제를 따르십시오 .

<input  type="submit" value="Add" onclick="addNewPayment();return false;">

0

상단과 하단에 각각 하나씩 두 개의 링크가 포함 된 페이지를 작성하십시오. 맨 위 링크를 클릭하면 페이지가 맨 아래 링크가있는 페이지 맨 아래로 스크롤해야합니다. 하단 링크를 클릭하면 페이지가 페이지 상단으로 스크롤되어야합니다.


0
<a onclick="yourfunction()">

이것은 잘 작동합니다. href = "#"를 추가 할 필요가 없습니다.


0

CSS를 확인하고 싶을 수도 있습니다. 예를 들면 다음과 같습니다. https://css-tricks.com/the-checkbox-hack/position: absolute; top: -9999px;있습니다. onclick="whatever"여전히 클릭 한 요소의 절대 위치로 점프하기 때문에 Chrome에서 구피입니다 .

를 제거 position: absolute; top: -9999px;하면 display: none;도움 이 될 수 있습니다.


0

부트 스트랩 3 축소의 경우 앵커에서 데이터 대상을 지정하지 않고 대상을 결정하기 위해 href를 사용하면 이벤트가 방지됩니다. 데이터 타겟을 사용하는 경우 이벤트를 직접 방지해야합니다.

<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#demo">Collapse This</button>

<div id="demo" class="collapse"> 
<p>Lorem ipsum dolor sit amet</p>
</div>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.