programing

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

batch 2023. 8. 9. 20:36
반응형

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

사진 갤러리를 만들고 있는데 사진을 검색할 때 쿼리 문자열과 제목을 변경할 수 있으면 좋겠습니다.

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

저는 이 훌륭한 게시물을 발견했고, 모범을 따르려고 했습니다.window.history.pushstate하지만 그건 저에게 효과가 없는 것 같아요.그리고 브라우저 기록을 수정하는 것에 대해 별로 신경 쓰지 않기 때문에 이상적인 것인지 잘 모르겠습니다.

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

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

UPDATE에서 다음 메서드를 찾았습니다.

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

해시 수정을 찾고 있다면 솔루션이 정상적으로 작동합니다.그러나 쿼리를 변경하려면 말씀하신 대로 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

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);
        }
    }

// to remove the specific key
export function removeUrlParameter(paramKey) {
  const url = window.location.href
  console.log("url", url)
  var r = new URL(url)
  r.searchParams.delete(paramKey)
  const newUrl = r.href
  console.log("r.href", newUrl)
  window.history.pushState({ path: newUrl }, '', newUrl)
}

URL 인터페이스를 사용하여 미래의 개발에 도움이 되는 오래된 질문, 현대식 답변:

const url = new URL(window.location);
url.searchParams.set('key', value);
window.history.pushState(null, '', url.toString());

이렇게 하면 원하는 쿼리 매개 변수만 변경할 수 있습니다.

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);
    }
}

URL의 다른 부분을 건드리지 않고 단순히 쿼리 매개 변수를 업데이트하려는 경우 URL을 다시 빌드할 필요가 없습니다.다음을 사용합니다.

const addQueryParam = (key, value) => {
  const url = new URL(window.location.href);
  url.searchParams.set(key, value);
  window.history.pushState({}, '', url.toString());
};

const getQueryParam = (key) => {
  const url = new URL(window.location.href);
  return url.searchParams.get(key) || '';
};

저는 다음 자바스크립트 라이브러리를 성공적으로 사용했습니다.

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

HTML5 history API를 지원하며, 이전 브라우저의 폴백 방식(# 사용)을 지원합니다.

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

여기에 응답하는 모든 사람이 해시를 잊어버린 것처럼 보이기 때문에 모든 URL 매개 변수를 유지하기 위해 사용하는 코드를 추가하고 싶습니다.

const urlParams = new URLSearchParams(window.location.search);

/// Change some part of the URL params

if (history.pushState) {
  const newurl =
    window.location.protocol +
    "//" +
    window.location.host +
    window.location.pathname +
    "?" +
    urlParams.toString() +
    window.location.hash;
  window.history.replaceState({ path: newurl }, "", newurl);
} else {
  window.location.search = urlParams.toString();
}

그렇다면 역사 API가 바로 당신이 찾고 있는 것입니다.기존 브라우저도 지원하려면 브라우저가 기록 API를 제공하지 않는 경우 URL의 해시 태그를 조작하는 데 도움이 되는 라이브러리를 찾습니다.

저는 파비오와 아람의 대답에 조금 더 덧붙여야겠다고 생각했습니다.저는 가끔 URL의 해시를 보존하고 싶을 수도 있다고 생각했습니다.그러나 일반적으로 그렇지 않기 때문에 이 매개 변수를 기본값으로 설정합니다.false.

replaceState여전히 Chrome에서 페이지 제목을 설정하지 않습니다.그래서 제목이 제공되면 제목을 바꾸기 위해 몇 줄을 추가했습니다.

function insertUrlParam(key, value, title = '', preserve_hash = false) {
    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();
        if(preserve_hash) newurl = newurl + window.location.hash;
        let oldTitle = document.title;
        if(title !== '') {
            window.history.replaceState({path: newurl}, title, newurl);
            if(document.title !== title) { // fallback if above doesn't work
                document.title = title;
            }
        } else { // in case browsers ever clear titles set with empty string
            window.history.replaceState({path: newurl}, oldTitle, newurl);
        }
    }
}

언급URL : https://stackoverflow.com/questions/10970078/modifying-a-query-string-without-reloading-the-page

반응형