On-window.location.hash-변경 하시겠습니까?


558

탐색을 위해 Ajax와 해시를 사용하고 있습니다.

window.location.hash이와 같이 변경 되었는지 확인하는 방법 이 있습니까?

http://example.com/blah # 123 ~ http://example.com/blah # 456

문서가로드 될 때 확인하면 작동합니다.

그러나 #hash 기반 탐색 기능이 있으면 브라우저에서 뒤로 버튼을 누를 때 작동하지 않습니다 (따라서 blah # 456에서 blah # 123으로 이동).

주소 상자 안에 표시되지만 JavaScript로는 잡을 수 없습니다.


6
이 jquery 플러그인을 확인하십시오 : github.com/cowboy/jquery-hashchange
Xavi

9
History.js 는 HTML5 상태 관리 기능을 지원하므로 (더 이상 해시를 사용할 필요가 없습니다!) 해시 변경을 사용하여 HTML4 브라우저로 정상적으로 성능을 저하시킵니다. jQuery, MooTools 및 프로토 타입을 즉시 지원합니다.
balupton

@balupton, 실제로 URL 변경을 피드백으로 사용하지 않는 한 "새 페이지"가 ​​히스토리에 삽입되었다는 피드백을 사용자에게 제공 하려면 해시를 사용해야합니다 .
Pacerier


흠 ... 난 당신이 moar 필요가 있다고 생각 jQuery를
RaisingAgent

답변:


617

실제로이 작업을 수행하는 유일한 방법 (그리고 '실제로 간단한 역사'가이를 수행하는 방법입니다)은 현재 해시를 계속 확인하는 간격을 설정하고 이전과 비교하여 간격을 설정하여 구독자를 변경하도록 구독합니다 해시가 변경되면 발생하는 이벤트입니다. 완벽하지는 않지만 브라우저는이 이벤트를 기본적으로 지원하지 않습니다.


이 답변을 최신 상태로 유지하려면 업데이트하십시오.

jQuery를 사용하는 경우 (오늘날 다소 기초가되어야 함) 멋진 해결책은 jQuery가 제공하는 추상화를 사용하여 이벤트 객체를 사용하여 창 객체에서 hashchange 이벤트를 수신하는 것입니다.

$(window).on('hashchange', function() {
  //.. work ..
});

여기서 좋은 점은 해시 체인지 지원에 대해 걱정할 필요가없는 코드를 작성할 수 있지만 다소 덜 알려진 jQuery 기능인 jQuery special events의 형태로 마술을 수행해야한다는 것 입니다.

이 기능을 사용하면 기본적으로 어떤 사람이 처음으로 어떤 방식 으로든 이벤트를 사용하려고 할 때 (예 : 이벤트 바인딩) 이벤트에 대해 일부 설정 코드를 실행하게됩니다.

이 설정 코드에서 기본 브라우저 지원을 확인할 수 있으며 브라우저가 기본적으로이를 구현하지 않는 경우 단일 타이머를 설정하여 변경 사항을 폴링하고 jQuery 이벤트를 트리거 할 수 있습니다.

이것은 코드 가이 지원 문제를 이해해야 할 필요성을 완전히 풀어줍니다.이 종류의 특수 이벤트 구현은 간단합니다 (단순한 98 % 작업 버전을 얻기 위해). 그러나 누군가 다른 사람이 이미 가지고있을 때 왜 그렇게합니까 ?


7
IE8은 그렇습니다. 더 올 것
Sergey Ilinsky

28
최신 Firefox 빌드 (3.6 알파)는 이제 기본 해시 변경 이벤트도 지원합니다. developer.mozilla.org/en/DOM/window.onhashchange 이 이벤트를 확인하는 것이 좋습니다. 그러나 IE8이 이벤트를 알려줍니다. IE7 compat 모드에서 실행될 때 존재합니다. 슬프게도 이벤트가 실행되지 않습니다. 이벤트를 확인해야하며 브라우저가 IE7이 아닌 것으로 보입니다. 한숨 (또는 이벤트를 트리거하려고 시도) IE의 fireEvent 메소드 사용).
meandmycode

8
글을 쓰는 시점에서 WebKit도 hashchange이벤트를 시작하지만 Safari (안정적)는 아직 발생하지 않습니다.
jholster

51
또 다른 업데이트를 추가하기 위해 hashchange이벤트가 광범위하게 지원됩니다. caniuse.com/#search=hash
Paystey

19
원치 않는 jQuery 답변이 고통이라고 생각하는 유일한 사람입니까?
Luc

290

HTML5 hashchange이벤트를 지정합니다 . 이 이벤트는 이제 모든 최신 브라우저에서 지원됩니다 . 다음 브라우저 버전에서 지원이 추가되었습니다.

  • 인터넷 익스플로러 8
  • Firefox 3.6
  • 크롬 5
  • 사파리 5
  • 오페라 10.6

20
업데이트 : 2011 년 6 월의 같은 FF 5, 사파리 5, 및 크롬 12 지원 이벤트
james.garriss

2
다음은 hashchangeCanIUse 페이지입니다 . 여기 quirksmode의 hashchange가 있습니다 . 대소 문자 구분과 관련하여 IE 지원은 버그가 있습니다.
Tobu

3
@body, 코멘트 섹션의 답변에 계속 추가 할 필요가 없습니다. 이것이 바로 "편집"버튼입니다. :)
Michael Martin-Smucker 2016 년

15
사용법 :window.onhashchange = function() { doYourStuff(); }
Chris

4
hashchange 이벤트 의 MDN 문서 .
Dabowheel

52

Internet Explorer 7 및 Internet Explorer 9의 if경우이 설명은 Windows에서 "onhashchange"에 대해 true를 제공하지만 window.onhashchange실행되지는 않으므로 해시를 저장하고 변경 여부에 상관없이 100 밀리 초마다 확인하는 것이 좋습니다. 모든 버전의 Internet Explorer

    if (("onhashchange" in window) && !($.browser.msie)) {
         window.onhashchange = function () {
              alert(window.location.hash);
         }
         // Or $(window).bind( 'hashchange',function(e) {
         //       alert(window.location.hash);
         //   });
    }
    else {
        var prevHash = window.location.hash;
        window.setInterval(function () {
           if (window.location.hash != prevHash) {
              prevHash = window.location.hash;
              alert(window.location.hash);
           }
        }, 100);
    }

편집-jQuery 1.9부터는 $.browser.msie지원되지 않습니다. 출처 : http://api.jquery.com/jquery.browser/


14

IE 브라우저에서 History 및 window.location.hash를 다루는 많은 트릭이 있습니다.

  • 원래 질문에서 말했듯이 a.html # b 페이지에서 a.html # c 페이지로 이동 한 다음 뒤로 버튼을 누르면 브라우저가 해당 페이지가 변경되었음을 알 수 없습니다. a.html # b 또는 a.html # c에 있더라도 window.location.href는 'a.html # c'가됩니다.

  • 실제로 a.html # b 및 a.html # c는 페이지에 '<a name="#b">'및 '<a name="#c">'요소가 있는 경우 에만 히스토리에 저장됩니다 .

  • 그러나 페이지 안에 iframe을 넣은 경우 해당 iframe에서 a.html # b에서 a.html # c로 이동 한 다음 뒤로 버튼을 누르면 iframe.contentWindow.document.location.href가 예상대로 변경됩니다.

  • 코드에서 'document.domain = something '을 사용하면 iframe.contentWindow.document.open () '에 액세스 할 수 없습니다 (많은 기록 관리자가이를 수행함)

나는 이것이 실제 반응이 아니라는 것을 알고 있지만 IE 역사 기록은 누군가에게 유용 할 것입니다.



11

Ben Alman은 이것을 처리하기위한 훌륭한 jQuery 플러그인을 가지고 있습니다 : http://benalman.com/projects/jquery-hashchange-plugin/

jQuery를 사용하지 않는다면 해부에 대한 흥미로운 참조가 될 수 있습니다.


Ben Alman 플러그인은 더 이상 유지되지 않는 것 같습니다. 그래도 많은 포크가 있습니다.
Mnebuerquo

9

"window.location"개체의 "hash"속성에서 관찰자 ( "watch"메서드)를 쉽게 구현할 수 있습니다.

Firefox에는 객체의 변경 사항을 감시 하는 자체 구현이 있지만 다른 브라우저 (예 : JavaScript의 객체 속성 변경 사항 감시) 와 같은 다른 구현을 사용하는 경우 다른 브라우저에서 트릭을 수행합니다.

코드는 다음과 같습니다.

window.location.watch(
    'hash',
    function(id,oldVal,newVal){
        console.log("the window's hash value has changed from "+oldval+" to "+newVal);
    }
);

그런 다음 테스트 할 수 있습니다.

var myHashLink = "home";
window.location = window.location + "#" + myHashLink;

물론 그것은 관찰자 기능을 유발할 것입니다.


더 나은 사용법 : window.location 대신 window.location.href
Codebeat

3
그는 window.location이 아니라 window.location.hash를보고 있습니다.
정의되지 않은

1
@BrianMortenson : docs ( developer.mozilla.org/en-US/docs/JavaScript/Reference/… ) 에 따르면 watch변경되는 속성을 소유 한 객체에 적용 하고 관찰해야합니다.
gion_13

@ gion_13 예, 그것이 제가 지적하려고했던 바로 그 것입니다. '그는'당신을 의미했고, 그것은 Erwinus의 의견에 관한 것입니다. 나는 더 분명 했어야했다. 명확한 의견을 보내 주셔서 감사합니다.
정의되지 않은

7

나는 이것을 반응 응용 프로그램에서 사용하여 사용자가 어떤보기에 따라 URL이 다른 매개 변수를 표시하게했습니다.

나는 사용하여 해시 매개 변수를 보았다

window.addEventListener('hashchange', doSomethingWithChangeFunction());

그때

doSomethingWithChangeFunction () { 
    // Get new hash value
    let urlParam = window.location.hash;
    // Do something with new hash value
};

치료를 해왔으며 앞으로 및 뒤로 브라우저 버튼과 함께 작동하며 브라우저 기록에서도 작동합니다.


1
당신의 addEventListener전화, 당신은 제거해야합니다 ()에서doSomethingWithChangeFunction
제이슨 S

()를 제거 할 이유를 제공 할 수 있습니까? 나는 그것이 어느 쪽에서도 작동 할 것이라는 것을 알고 있으며 코드가 적을수록 더 좋은 옵션이지만 이것을 백업해야 할 실질적인 이유가 없다면 까다로워 보입니다.
Sprose

6
? 작동하지 않아야합니다 (). addEventListener함수는 함수에 전달할 수 있어야합니다. doSomethingWithChangeFunction함수입니다. doSomethingWithChangeFunction()이 함수의 반환 값이며이 경우 함수가 아닙니다.
Jason S

6

적절한 구현은 http://code.google.com/p/reallysimplehistory/ 에서 찾을 수 있습니다 . Internet Explorer에서 위치 해시를 수동으로 수정하면 전체 기록 스택이 재설정됩니다 (브라우저 문제이므로 해결할 수 없음).

Internet Explorer 8은 "hashchange"이벤트를 지원하며 HTML5의 일부가되어 다른 브라우저를 따라 잡을 수 있습니다.


1

또 다른 훌륭한 구현은 브라우저에서 지원하는 경우 기본 onhashchange 이벤트를 사용하는 jQuery History 입니다. 또한 특정 상태에 바인딩 할 수있는 훌륭한 인터페이스를 제공합니다.

주목할만한 또 다른 프로젝트는 jQuery Ajaxy 로, jQuery History가 믹스에 아약스를 추가하는 확장 기능입니다. 해시와 함께 ajax를 사용하기 시작할 때 꽤 복잡합니다 !


1
var page_url = 'http://www.yoursite.com/'; // full path leading up to hash;
var current_url_w_hash = page_url + window.location.hash; // now you might have something like: http://www.yoursite.com/#123

function TrackHash() {
    if (document.location != page_url + current_url_w_hash) {
        window.location = document.location;
    }
    return false;
}
var RunTabs = setInterval(TrackHash, 200);

이제는 ... 이제 뒤로 또는 앞으로 버튼을 누를 때마다 새 해시 값에 따라 페이지가 다시로드됩니다.


평가 문자열을 사용하지 마십시오
Vitim.us

1

클라이언트 측 라우팅에 path.js를 사용하고 있습니다. 나는 간결하고 가벼운 것으로 판명되었으며 (NPM에도 게시 됨) 해시 기반 탐색을 사용합니다.

path.js NPM

path.js GitHub


0

jQuery 플러그인 HUtil을 사용하고 인터페이스와 같은 YUI History를 작성 했습니다.

한 번 확인하십시오. 도움이 필요하면 도와 드릴 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.