web-dev-qa-db-fra.com

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

Je crée une galerie de photos et j'aimerais pouvoir modifier la chaîne de requête et le titre lors de la consultation des photos.

Le comportement que je recherche est souvent observé dans certaines implémentations de page continue/infinie, où, pendant le défilement, la chaîne de requête continue à 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 de sûr pour les principaux navigateurs.

J'ai trouvé ce très bon message , et j'essayais 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 veux juste pouvoir offrir la possibilité de mettre en signet la photo actuellement affichée, sans recharger la page à chaque changement de photo.

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

UPDATE a trouvé cette méthode:

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

cela semble fonctionner pour moi, mais je suis sur un nouveau chrome .. cela causerait-il probablement des problèmes avec les anciens navigateurs? 

68
Sonic Soul

Si vous recherchez une modification par hachage, votre solution fonctionne bien. Toutefois, si vous souhaitez modifier la requête, vous pouvez utiliser le pushState, comme vous l'avez dit. Voici un exemple qui pourrait vous aider à le mettre en œuvre correctement. J'ai testé et cela a bien fonctionné:

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

Il ne recharge pas la page, mais vous permet uniquement de modifier la requête d'URL. Vous ne pourrez pas modifier le protocole ni les valeurs de l'hôte. Et bien sûr, cela nécessite des navigateurs modernes capables de traiter l'API HTML5 History.

Pour plus d'informations:

http://diveintohtml5.info/history.html

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

118
Fabio Nolasco

J'ai utilisé la bibliothèque JavaScript suivante avec un grand succès: 

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

Il supporte l'API d'historique HTML5 ainsi qu'une méthode de secours (#) pour les navigateurs plus anciens.

Cette bibliothèque est essentiellement un polyfill autour de `history.pushState '.

6
Ian Newson

En me basant sur la réponse de Fabio, j'ai créé deux fonctions qui seront probablement utiles à quiconque tomberait 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 modifiera ce paramètre avec la nouvelle valeur:

//function to remove query params form a url
function removeURLParameter(url, parameter) {
    //prefer 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 insertParam(key, value) {
    if (history.pushState) {
        // var newurl = window.location.protocol + "//" + window.location.Host + search.pathname + '?myNewUrlQuery=1';
        var currentUrl = window.location.href;
        //remove any param for the same key
        var currentUrl = removeURLParameter(currentUrl, key);

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

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

Ensuite, l’API d’historique correspond exactement à ce que vous recherchez. Si vous souhaitez également prendre en charge les navigateurs hérités, recherchez une bibliothèque qui manipule la balise hash de l'URL si le navigateur ne fournit pas l'API d'historique.

0
chucktator

Je souhaite améliorer la réponse de Fabio et créer une fonction qui ajoute une clé personnalisée à la chaîne d'URL sans recharger la page.

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
Aram Hovhannisyan