J'ai une fonctionnalité contextuelle personnalisée. Ce que je veux, c'est que le bouton de retour du navigateur ferme cette fenêtre contextuelle.
Mon scénario idéal serait de NE PAS afficher de hashtag dans la barre d'URL.
J'ai essayé de mettre window.history. pushState ('forward', null, ''); dans ma fonction showPopup () puis en faisant ce qui suit:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="popup-link">Click</button>
<div class="popup">
<button class="popup-close">x</button>
<!-- popup content here -->
</div>Cela fonctionne mais le problème est que lorsque je ferme manuellement la fenêtre contextuelle, je dois appuyer deux fois sur le bouton retour pour revenir à la page précédente (évidemment parce qu'une entrée d'historique du navigateur a été ajoutée lors de l'ouverture de la fenêtre contextuelle).
Quelle est la meilleure façon de procéder? Cela peut-il être fait sans ajouter une entrée d'historique du navigateur? Ce que j'essaye de faire, c'est de reproduire le comportement d'une application mobile. Appuyez sur le bouton de retour dans une application mobile pour supprimer généralement les modaux ouverts ou les menus contextuels.
.popup {
background-color: #ccc;
width: 300px;
height: 300px;
display: none;
}
.popup.active {
display: block;
}
$('.popup-link').click(function() {
showPopup();
});
$('.popup-close').click(function() {
hidePopup();
});
function showPopup() {
$('.popup').addClass('active');
}
function hidePopup() {
$('.popup').removeClass('active');
}
$(window).on('popstate', function () {
closePopup();
});
7 Réponses :
Cependant, je ne recommande pas de remplacer la gestion habituelle de l'historique du navigateur (bouton retour) pour l'utiliser à votre guise ....
Je pense que la seule chose que vous avez manquée dans votre exemple est que le bouton de fermeture ne doit pas fermer le modal tout seul, mais simplement exécuter un événement backbutton (qui finira par fermer le modal).
Cette solution simple fonctionnera comme vous le souhaitez.
regardez le message ici: ux.stackexchange.com/questions/100866/...
Il n'est pas possible de le faire sans ajouter des entrées d'historique du navigateur car vous ne pouvez pas remplacer le comportement du bouton Précédent, voir Intercepter l'appel au bouton de retour de mon application AJAX: je ne veux rien faire
La réponse de Sujumayas est une bonne option, vous devriez cependant introduire une variable supplémentaire pour éviter des problèmes avec l'historique lors de l'ouverture de plusieurs fenêtres contextuelles (par exemple, en cliquant sur le bouton plusieurs fois)
Voici un exemple de code possible: p >
let popupOpen = false;
$(".popup-link").click(function() {
showPopup();
});
$(".popup-close").click(function() {
window.history.back();
});
function showPopup() {
if (popupOpen) {
window.history.back();
}
popupOpen = true;
window.history.pushState("forward", null, "");
$(".popup").addClass("active");
}
function hidePopup() {
popupOpen = false;
$(".popup").removeClass("active");
}
$(window).on("popstate", function() {
hidePopup();
});
De plus, veuillez noter que vous pourriez avoir des problèmes avec Opera Mini: https: //caniuse.com/#search=history
@GSTAR Je pense que c'est ce que vous recherchez.
Je fais déjà quelque chose comme ça, et cela fonctionne bien avec le bouton de retour du navigateur et en appuyant sur le bouton de retour d'Android. Je n'affiche pas non plus de hashtag dans la barre d'URL.
Voici le talon (j'ai juste essayé de l'appliquer à votre scénario):
function freezeHistory() {
window.history.pushState({}, window.document.title, window.location.href);
}
function goBack() {
/*
Custom history back actions: close panel, close popup, close drop-down menu
*/
var popupOpen = $(".popup.active").length > 0;
if(popupOpen) {
hidePopup();
return false;
}
window.history.back();
return true;
}
function showPopup() {
$('.popup').addClass('active');
freezeHistory();
}
function hidePopup() {
$('.popup').removeClass('active');
}
$(window).on("popstate", function(e) {
/*
Browsers tend to handle the popstate event differently on page load.
Chrome (prior to v34) and Safari always emit a popstate event on page load,
but Firefox doesnât.
*/
goBack();
})
Si cela a gagné ' t travailler pour vous hors de la boîte, c'est parce qu'à mon humble avis, vous devrez peut-être clarifier un peu comment vous comptez gérer l'historique de la page. N'hésitez pas à ajouter plus de détails à votre question si cela ne fonctionne pas comme prévu maintenant, mais de toute façon, je crois fermement que vous avez eu l'idée et que vous êtes en mesure de l'appliquer dans le scénario de votre application Web. p>
Ouvrez la fenêtre contextuelle et essayez d'aller et venir avec les boutons d'historique du navigateur
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="popup-link">Click</button>
<div class="popup">
<button class="popup-close">x</button>
<!-- popup content here -->
</div>
.popup {
background-color: #ccc;
width: 300px;
height: 300px;
display: none;
}
.popup.active {
display: block;
}
$(document).ready(function () {
// manage popup state
var poped = false;
$('.popup-link').click(function () {
// prevent unwanted state changtes
if(!poped){
showPopup();
}
});
$('.popup-close').click(function () {
// prevent unwanted state changtes
if(poped){
hidePopup();
}
});
function showPopup() {
poped = true;
$('.popup').addClass('active');
// push a new state. Also note that this does not trigger onpopstate
window.history.pushState({'poped': poped}, null, '');
}
function hidePopup() {
poped = false;
// go back to previous state. Also note that this does not trigger onpopstate
history.back();
$('.popup').removeClass('active');
}
});
// triggers when browser history is changed via browser
window.onpopstate = function(event) {
// show/hide popup based on poped state
if(event.state && event.state.poped){
$('.popup').addClass('active');
} else {
$('.popup').removeClass('active');
}
};
Vous pouvez ajouter window.history.go (-2) à votre popstate. Cela devrait vous ramener deux fois, ce qui serait votre page d'origine avant le modal car pushState a ajouté une entrée à votre objet d'historique.
Inversement, vous pouvez utiliser history.back (2) Utilisez window.location.href pour parcourir 2 pages revenir et recharger
Lancez simplement window.history.back (); lors de la fermeture du popup.
$('.popup-close').click(function() {
hidePopup();
window.history.back();
});
Vous auriez deux options pour implémenter ceci:
Option 1: Utilisation de l'événement window.beforeunload . référence
$('.popup-link').click(function() {
showPopup();
window.history.pushState('popup-open', null, '');
$(window).on('popstate', hidePopup);
});
$('.popup-close').click(function() {
if(history.state == 'popup-open') {
window.history.back();
}
hidePopup();
});
function hidePopup() {
$(window).off('popstate', hidePopup);
$('.popup').removeClass('active');
}
L'option 1 génère l'erreur "Uncaught RangeError: taille maximale de la pile des appels dépassée" dans la console à cause de cela, "$ (window) .off (" beforeunload ", hidePopup);"
Changer le comportement standard est une expérience utilisateur terrible. Pourquoi feriez-vous une telle chose?
Eh bien, vous pourriez affirmer que ce "comportement standard" est une mauvaise expérience utilisateur - car beaucoup d'utilisateurs maintenant (en particulier les utilisateurs d'applications mobiles) sont habitués à appuyer pour rejeter les fenêtres contextuelles et les invites.
Eh bien, vous argumenteriez sur un argument incorrect.
Qu'entendez-vous par
fermer manuellement la fenêtre contextuelle? Voulez-vous dire fermer le popup en utilisant le boutoncloseavec la classepopup-close?Même si votre problème n'existe plus ou a été résolu autrement, vous devez suivre les réponses affichées.