>  기사  >  웹 프론트엔드  >  JavaScript는 Refresh_javascript 기술 없이 브라우저의 앞으로 및 뒤로 기능을 구현합니다.

JavaScript는 Refresh_javascript 기술 없이 브라우저의 앞으로 및 뒤로 기능을 구현합니다.

WBOY
WBOY원래의
2016-05-16 16:32:101746검색

저는 최근 백본을 배우고 있습니다. 백본을 이해하려면 먼저 스파를 이해해야 합니다. 스파를 이해하려면 먼저 페이지를 새로 고치지 않고도 단일 페이지 애플리케이션이 어떻게 URL을 변경할 수 있는지 이해해야 합니다.

다른 페이지로 이동하는 것에 비해 AJAX는 사용자의 탐색 경험을 크게 향상시켰다고 할 수 있습니다. 페이지 전환 사이에 흰색 화면을 볼 필요가 없다는 점은 매우 즐겁습니다. 그러나 많은 초기 AJAX 애플리케이션은 브라우저의 앞으로 및 뒤로 기능을 지원하지 않았습니다. 이로 인해 사용자는 웹사이트 어디를 탐색하더라도 새로 고침을 하면 즉시 원래 위치로 돌아가고 사용자는 브라우저의 기능을 사용할 수 없었습니다. 탐색 기록을 전환하는 앞으로 및 뒤로 기능.

첫 번째 문제는 쿠키나 localStorage를 사용하여 애플리케이션 상태를 기록하고, 페이지를 새로 고칠 때 이 상태를 읽은 다음 해당 Ajax 요청을 보내 페이지를 변경하면 됩니다. 하지만 두 번째 문제는 매우 골치 아픈 문제입니다. 먼저 최신 브라우저의 솔루션에 대해 이야기해 보겠습니다.

HTML5 솔루션

HTML5의 정방향 및 역방향 구현 방식을 이해하려면 먼저 기록 개체와 위치 개체를 이해해야 합니다.

기록 개체

히스토리 개체 속성

1.length: 브라우저 기록 목록의 URL 수를 반환합니다. 사용자가 현재 탭의 페이지를 방문할 때마다 이 숫자는 1씩 증가합니다. 개인정보 보호를 위해 URL의 특정 내용은 표시되지 않습니다.
2.state: 현재 URL과 관련된 객체로, pushState 및 replacementState를 통해서만 추가하거나 수정할 수 있습니다. 이를 사용하여 URL과 관련된 정보를 저장할 수 있습니다.

히스토리 객체 방식

1.history.back()

이 메서드에는 매개변수가 없습니다. 실행된 후에는 이전에 검색한 페이지로 돌아가며 이는 브라우저의 뒤로 버튼을 클릭하는 것과 같습니다.

2.history.forward()

이 메서드는 매개변수가 없습니다. 실행되면 뒤로 가기 전에 검색했던 페이지로 돌아가며, 이는 브라우저의 앞으로 버튼을 클릭하는 것과 같습니다.

3.history.go(번호)

이 메서드는 정수 변수 매개변수를 허용합니다.history.go(-1)는 한 페이지 뒤로 이동하는 것과 동일하고,history.go(1)은 한 페이지 앞으로 이동하는 것과 동일하며,history.go(0)는 현재 페이지.

4.history.pushState(상태, 제목, URL)

페이지를 새로 고치지 않고 URL을 변경하는 방법의 핵심은 이 메서드를 사용하면 현재 페이지의 location.href가 변경되고 현재의history.state 객체가 수정됩니다. 이 메소드는

세 가지 매개변수를 허용합니다.

1.state: 현재 URL과 관련된 객체입니다.
2.title: 페이지 제목이지만 모든 브라우저에서는 이를 무시합니다. 제목을 변경하려면 document.title을 사용해야 합니다.
3.url: 현재 페이지와 동일한 도메인에 있는 URL, location.href가 이 값이 됩니다.

5.history.replaceState(상태, 제목, URL)

이 방법은 위와 동일하지만,history.length는 변경되지 않고,history.state와 location.href만 수정됩니다.

pushState 및 replacementState의 세 번째 매개변수는 도메인을 교차할 수 없으며 브라우저의 popstate 이벤트 및 onhashchange 이벤트를 트리거하지 않습니다(chrome33에서 테스트됨).

위치 개체

앞으로/뒤로 버튼 클릭과 이벤트 기록 외에도 위치 메소드를 통해 URL을 변경하고 위치 속성을 수정할 수도 있습니다.

위치 객체의 속성(읽기 및 쓰기):

1.host: 도메인 이름 포트 번호
2.호스트 이름: 도메인 이름
3.port: 포트 번호
4.프로토콜: 프로토콜
5.href: 전체 경로
6.origin: 프로토콜 도메인 이름 포트
7.해시: 파운드 기호(#)로 시작하는 URL(해시)
8.pathname: 문서 경로 문서 이름
9.검색:(?)뒤의 내용

location.href 또는 location.hash를 변경하면 새로 고침이 없는 목적을 달성할 수 있습니다.

위치 개체 방법:

1.할당: url 값을 변경하고 현재 url을 기록 History.length에 추가하면 1씩 늘어납니다. location.asig('#' x)는 URL을 변경하지만 페이지를 새로 고치지는 않습니다.
2.다시 로드: 페이지를 새로 고칩니다.
3.replace: url 값을 변경하지만, History.length는 변경되지 않습니다. 사용법은 할당과 동일합니다.

팝스테이트 이벤트

예를 들어 URL이 변경되면 사용자가 앞으로/뒤로 버튼을 클릭하는 경우,history.go(n)(n은 0이 아님), location.hash = x(x는 현재 위치와 동일하지 않음) 해시)가 이 이벤트를 트리거합니다. 이를 사용하여 URL을 모니터링하여 다양한 기능을 구현할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

​ window.onpopstate = function(){
               //sth
}

해시체인지 이벤트

해시 값을 변경하면 popstate 이벤트가 트리거되지만, popstate 이벤트가 트리거된다고 해서 반드시 onhashchange 이벤트가 트리거되는 것은 아닙니다. 테스트됨:

1.hash는 변경되지만 location.pathname은 변경되지 않고 그대로 유지되면 History.pushState(", ", '#abc')와 같은 onhashchange 이벤트가 트리거됩니다.
2. hash와 location.pathname이 함께 변경되는 경우(history.pushState(”, ”, ‘a#abc’);

와 같이) 트리거되지 않습니다.

오래된 브라우저에서 작성하는 방법

오래된 브라우저도 pushState와 replacementState를 지원하지 않기 때문에 popstate를 통한 URL 변경 모니터링(사실 이 방법은 지원되지 않습니다)이 불가능합니다. 그런 다음 url# 이후의 콘텐츠를 변경해야만 새로 고침을 수행할 수 없지만 onhashchange를 지원하지 않으므로 URL 변경에 무관심합니다(페이지가 페이지 ID에 해당하는 위치로 스크롤된다는 점 제외). 그런 다음 큰 트릭인 폴링에만 의존할 수 있으며 setInterval을 설정하여 URL 값을 모니터링할 수 있습니다. 이렇게:

코드 복사 코드는 다음과 같습니다.

var prevHash = window.location.hash
var 콜백 = 함수(){...}
window.setInterval(function() {
If (window.location.hash != prevHash) {
         prevHash = window.location.hash
        콜백(prevHash)
}
}, 100);

물론 이런 식으로 작성하는 것은 매우 답답한 일입니다. 해시를 변경하기 위해 페이지에서 ID가 포함된 태그를 클릭하는 것을 고려하지 않는다면 디자인 패턴을 사용하여 모니터링 URL을 우아하게 구현할 수 있습니다. 예를 들어, 클래식 관찰자 패턴에서는 해시 변경 기능을 구현하는 데 클래스가 특별히 사용되며, URL 변경을 모니터링하려는 모든 클래스(관찰자)가 이(관찰) 클래스를 구독합니다.

코드 복사 코드는 다음과 같습니다.

//url 클래스 변경
함수 UrlChanger() {
var _this = this;
This.observers = [];
//관찰자 추가
This.addObserver = function(obj) {...}
//관찰자 삭제
This.deleteObserver = function(obj) {...}
//관찰자에게 알림
This._notifyObservers = function() {
      var 길이 = _this.observers.length;
console.log(길이)
for(var i = 0; i ​​​​​​ _this.observers[i].update();
}
}
//URL 변경
This.changeUrl = 함수(해시) {
           window.location.hash = 해시;
_this._notifyObservers();
}
}
//듣기 수업
함수 oneOfObservers() {
var _this = this;
This.update = function() {...}
}
//구현
var o1 = 새로운 UrlChanger();
var o2 = 새로운 oneOfObservers();
o1.addObserver(o2);
o1.changeUrl('fun/arg1/arg2/');
//o2가 작업을 수행했습니다...
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.