페이지를 다시로드하지 않고 쿼리 문자열 수정


114

사진 갤러리를 만들고 있는데 사진을 검색 할 때 쿼리 문자열과 제목을 변경할 수 있기를 원합니다.

내가 찾고있는 동작은 연속 / 무한 페이지의 일부 구현에서 자주 볼 수 있습니다. 여기서 쿼리 문자열을 아래로 스크롤하는 동안 페이지 번호 ( http://x.com?page=4 ) 등이 계속 증가합니다 . 이론상 간단하지만 주요 브라우저에서 안전한 것을 원합니다.

이 훌륭한 게시물을 찾았고 와 함께 예제를 따르려고 window.history.pushstate했지만 저에게 효과가없는 것 같습니다. 그리고 브라우저 기록을 수정하는 데는 신경 쓰지 않기 때문에 이상적인지 확실하지 않습니다.

사진이 변경 될 때마다 페이지를 다시로드하지 않고 현재보고있는 사진을 북마크하는 기능을 제공하고 싶습니다.

다음은 쿼리 문자열을 수정하는 무한 페이지의 예입니다. http://tumbledry.org/

UPDATE 는 다음 방법을 찾았습니다.

window.location.href = window.location.href + '#abc';

그것은 나를 위해 작동하는 것처럼 보이지만 나는 새로운 크롬을 사용하고 있습니다. 이전 브라우저에서 문제가 발생할 수 있습니까?


쿼리 문자열을 동적으로 업데이트하는 일부 예제 사이트에 대한 링크를 게시 할 수 있습니까? 나는 그것을 할 수 있다고 생각하지 않습니다,하지만 당신은 할 수 해시 값을 변경하고 당신이 원하는 것을 얻을 정도로 수 있습니다.
Pointy 2012-06-10



새로운 웹 Dropbox가 페이지 새로 고침없이 URL을 변경할 수있는 이유무엇입니까? 그리고 세 가지 질문은 그것의 중복으로 표시됩니다
쿠엔틴

@Quentin. 당신은 ... 하나 더 가까이 투표를 할 수 있습니다:)
gdoron 모니카 지원하고있다

답변:


185

해시 수정을 찾고 있다면 솔루션이 정상적으로 작동합니다. 그러나 쿼리를 변경하려면 말했듯이 pushState를 사용할 수 있습니다. 다음은이를 올바르게 구현하는 데 도움이 될 수있는 예입니다. 나는 테스트했고 잘 작동했습니다.

if (history.pushState) {
    var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?myNewUrlQuery=1';
    window.history.pushState({path:newurl},'',newurl);
}

페이지를 다시로드하지는 않지만 URL 쿼리 만 변경할 수 있습니다. 프로토콜이나 호스트 값을 변경할 수 없습니다. 물론 HTML5 History API를 처리 할 수있는 최신 브라우저가 필요합니다.

자세한 내용은:

http://diveintohtml5.info/history.html

https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history


6
나는 당신이 단축 될 수 있습니다 믿습니다 window.location.protocol + '//' + window.location.host단지에 : window.location.origin.
Garrett

4
또한 추가 정보를 위해 상대 경로는 history.pushState(). 실제 state인수도 필요하지 않습니다. 이 두 가지 모두 history.pushState(null, '', '/foo?bar=true')새 URL이 동일한 호스트 / 포트에있는 것처럼 간단한 작업을 수행 할 수 있음을 의미합니다 .
Blaskovicz

23
새 상태가 브라우저 기록에 표시되지 않도록 history.replaceState()하려면 동일한 인수를 사용할 수 있습니다 .
Blackus 2016

6
USE history.replaceState () 그렇지 않으면 브라우저에서 뒤로 버튼을 두 번 클릭해야합니다
Zhenya

4
최신 브라우저에 당신은 할 수 있습니다 :if (window.history.pushState) { const newURL = new URL(window.location.href); newURL.search = '?myNewUrlQuery=1'; window.history.pushState({ path: newURL.href }, '', newURL.href); }
앨런 밥티스타

8

Fabio의 대답을 바탕으로 나는이 질문에 걸림돌이되는 사람에게 유용 할 두 가지 기능을 만들었습니다. 이 두 함수를 insertParam()사용하면 키와 값을 인수로 사용하여 호출 할 수 있습니다 . URL 매개 변수를 추가하거나 동일한 키를 가진 쿼리 매개 변수가 이미 존재하는 경우 해당 매개 변수를 새 값으로 변경합니다.

//function to remove query params from a URL
function removeURLParameter(url, parameter) {
    //better to use l.search if you have a location/link object
    var urlparts= url.split('?');   
    if (urlparts.length>=2) {

        var prefix= encodeURIComponent(parameter)+'=';
        var pars= urlparts[1].split(/[&;]/g);

        //reverse iteration as may be destructive
        for (var i= pars.length; i-- > 0;) {    
            //idiom for string.startsWith
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {  
                pars.splice(i, 1);
            }
        }

        url= urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : "");
        return url;
    } else {
        return url;
    }
}

//function to add/update query params
function insertParam(key, value) {
    if (history.pushState) {
        // var newurl = window.location.protocol + "//" + window.location.host + search.pathname + '?myNewUrlQuery=1';
        var currentUrlWithOutHash = window.location.origin + window.location.pathname + window.location.search;
        var hash = window.location.hash
        //remove any param for the same key
        var currentUrlWithOutHash = removeURLParameter(currentUrlWithOutHash, key);

        //figure out if we need to add the param with a ? or a &
        var queryStart;
        if(currentUrlWithOutHash.indexOf('?') !== -1){
            queryStart = '&';
        } else {
            queryStart = '?';
        }

        var newurl = currentUrlWithOutHash + queryStart + key + '=' + value + hash
        window.history.pushState({path:newurl},'',newurl);
    }
}

당신의 함수가 설정삭제new URLSearchParams() 로 기본 메소드 보다 더 나은 방법은 무엇입니까? 두 경우 모두 우리는 그것을 역사에 넣어야합니다history.pushState()
AlexNikonov

1
new URLSearchParams()IE의 모든 버전을 지원하지 않습니다
jmona789

감사합니다 @ jmona789 이것이 저에게 완벽하게 작동했고 정확히 제가 찾던 것이 었습니다
mknopf

7

다음 JavaScript 라이브러리를 성공적으로 사용했습니다.

https://github.com/balupton/jquery-history

HTML5 히스토리 API와 이전 브라우저에 대한 대체 방법 (# 사용)을 지원합니다.

이 라이브러리는 본질적으로`history.pushState '주위의 폴리 필입니다.


대박! 모든 브라우저에서 테스트 했습니까 ??
소닉 소울

내 구현은 IE7 +, Firefox 3.6+, Safari 5 및 Chrome 16+에서 테스트되었습니다. 아마도 다른 브라우저에서도 작동 할 수 있지만,이를 사용하여 배포 된 여러 시스템에서 불만은 없었습니다.
이안 뉴슨

큰. 그래서 지금 당장 .. window.location.href에 쓸 때 & 대신 #을 넣으면 나를 위해 작동합니다. 페이지를 다시로드하지 않습니다. IE에서 테스트하면 고장날 것이라고 확신합니다. 어느 시점에서 귀하가 제안한 라이브러리로 갈 것입니다. 감사합니다
Sonic Soul

# 방법은 매우 광범위한 브라우저 지원을 제공한다는 점에서 좋은 방법입니다. URL의 # 부분이 브라우저에서 전송되지 않기 때문에 서버에 대한 요청에 해당 정보를 포함해야 할 때 상황이 복잡해질 수 있습니다. 내가 참조한 라이브러리를 포함하는 방법이 있습니다. 또한 HTML5 기록 API를 사용하면 URL을 전체적으로 짧게 만들고 상태를 복원하는 데 필요한 클라이언트 측 작업이 줄어 듭니다.
이안 뉴슨

# 방법은 소셜 미디어 공유에도 문제가 있습니다. Twitter, Facebook 및 아마도 다른 사람들은 미리보기를 만들거나 공유에 대한 링크를 만들 때 앵커 태그를 잘 사용하지 않습니다.
mirth23

5

Fabio의 답변을 개선하고 페이지를 다시로드하지 않고 URL 문자열에 사용자 정의 키를 추가하는 기능을 만들고 싶습니다.

function insertUrlParam(key, value) {
    if (history.pushState) {
        let searchParams = new URLSearchParams(window.location.search);
        searchParams.set(key, value);
        let newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + searchParams.toString();
        window.history.pushState({path: newurl}, '', newurl);
    }
}

0

그렇다면 히스토리 API는 정확히 당신이 찾고있는 것입니다. 레거시 브라우저도 지원하려면 브라우저가 히스토리 API를 제공하지 않는 경우 URL의 해시 태그 조작으로 대체되는 라이브러리를 찾으십시오.

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