231 votes

Modifier une chaîne de requête sans recharger la page

Je suis en train de créer une galerie de photos et j'aimerais pouvoir modifier la chaîne de requête et le titre lorsque les photos sont parcourues.

Le comportement que je recherche est souvent observé dans certaines implémentations de la page continue/infinie, où lorsque vous défilez vers le bas, la chaîne de requête continue d'incrémenter le numéro de page ( http://x.com?page=4 ), etc. Cela devrait être simple en théorie, mais je voudrais quelque chose qui soit sûr pour les principaux navigateurs.

J'ai trouvé cet excellent article et essayait de suivre l'exemple avec window.history.pushstate mais cela ne semble pas fonctionner pour moi. Et je ne suis pas sûr que ce soit l'idéal car je ne me soucie pas vraiment de modifier l'historique du navigateur.

Je souhaite simplement pouvoir offrir la possibilité de mettre en signet la photo actuellement visualisée, sans avoir à recharger la page à chaque fois que la photo est modifiée.

Voici un exemple de page infinie qui modifie la chaîne de requête : http://tumbledry.org/

MISE À JOUR a trouvé cette méthode :

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

7voto

jmona789 Points 992

En m'appuyant sur la réponse de Fabio, j'ai créé deux fonctions qui seront probablement utiles à toute personne tombant sur cette question. Avec ces deux fonctions, vous pouvez appeler insertParam() avec une clé et une valeur comme argument. Il ajoutera le paramètre URL ou, si un paramètre de requête existe déjà avec la même clé, il remplacera ce paramètre par la nouvelle valeur :

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

4voto

y-spreen Points 460

Puisque toutes les personnes qui répondent à cette question semblent oublier le hash, je souhaite ajouter le code que j'utilise pour conserver le hash. tous Paramètres 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();
}

0voto

chucktator Points 1648

Dans ce cas, l'API historique est exactement ce que vous recherchez. Si vous souhaitez également prendre en charge les anciens navigateurs, recherchez une bibliothèque qui se contente de manipuler la balise de hachage de l'URL si le navigateur ne fournit pas l'API d'historique.

0voto

Buttle Butkus Points 1717

J'ai pensé ajouter quelques éléments aux réponses de Fabio et d'Aram. J'ai pensé que je pourrais parfois souhaiter conserver le hash dans l'url. Mais ce n'est généralement pas le cas, c'est pourquoi j'ai mis ce paramètre par défaut à false .

replaceState ne définit toujours pas le titre de la page sur Chrome. J'ai donc ajouté quelques lignes pour modifier le titre, s'il est fourni.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X