Hvordan kan jeg stoppe nettleserens tilbakeknapp ved å bruke JavaScript?


Jeg lager en nettbasert quiz-applikasjon i PHP. Jeg vil begrense brukeren fra å gå tilbake under en eksamen.

Jeg har prøvd følgende skript, men det stopper timeren min.

Hva bør jeg gjøre?

Timmeren er lagret i filen cdtimer.js.

<script type="text/javascript">
    window.history.forward();
    function noBack()
    {
        window.history.forward();
    }
</script>

<body onLoad="noBack();" onpageshow="if (event.persisted) noBack();" onUnload="">

Jeg har eksamenstimeren som tar en varighet for eksamen fra en MySQL-verdi. Timeren starter deretter, men den stopper når jeg legger inn koden for å deaktivere tilbakeknappen. Hva er problemet mitt?

Svar #1

Det finnes mange grunner til at det å deaktivere tilbakeknappen egentlig ikke vil fungere. Din beste løsning er å advare brukeren:

window.onbeforeunload = function() { return "Your work will be lost."; };

Denne siden lister opp en rekke måter du kan prøve å deaktivere tilbakeknappen på, men ingen er garantert:

http://www.irt.org/script/311.htm

Svar #2

Jeg kom over dette, og trengte en løsning som fungerte korrekt og "fint" på en rekke nettlesere, inkludert Mobile Safari (iOS 9 på tidspunktet for publiseringen). Ingen av løsningene var helt riktige. Jeg tilbyr følgende (testet på Internet Explorer 11, Firefox, Chrome og Safari):

history.pushState(null, document.title, location.href);
window.addEventListener('popstate', function (event)
{
  history.pushState(null, document.title, location.href);
});

Merk følgende:

  • history.forward() (min gamle løsning) fungerer ikke på Mobile Safari --- det ser ut til å ikke gjøre noe (dvs. brukeren kan fortsatt gå tilbake). history.pushState() fungerer på alle av dem.
  • den tredje argumentet til history.pushState() er en url. Løsninger som sender en streng som 'no-back-button' eller 'pagename' ser ut til å fungere OK, helt til du prøver en oppdatering/last på nytt av siden, da blir en "Siden finnes ikke"-feil generert når nettleseren prøver å finne en side med det som URL. (Nettleseren vil også sannsynligvis inkludere den strengen i adressefeltet når du er på siden, noe som er stygt.) location.href bør brukes for URL-en.
  • det andre argumentet til history.pushState() er en tittel. Hvis man ser rundt på nettet, sier de fleste steder at det er "ikke brukt", og alle løsningene her bruker null for det. Men, i Mobile Safari i det minste, setter det sidens URL inn i historikk-menyen som brukeren kan få tilgang til. Men når den legger til en oppføring for et sidebesøk normalt, setter den inn sin tittel, som er å foretrekke. Så å sende document.title for det resulterer i samme oppførsel.

Svar #3

Det er generelt en dårlig idé å overstyre standardadferden til nettleseren. Et skript på klientsiden har ikke de nødvendige privilegiene til å gjøre dette av sikkerhetsmessige årsaker.

Det er også noen lignende spørsmål som er stilt,

  • Hvordan kan jeg forhindre at backspace-tasten navigerer tilbake?

  • Hvordan kan jeg forhindre nettleserens standard tilbaketast-handling for backspace-knappen med JavaScript?

Du kan-ikke faktisk deaktivere nettleserens tilbakeknapp. Du kan imidlertid bruke logikken din til å forhindre at brukeren navigerer tilbake, noe som vil skape et inntrykk av at den er deaktivert. Slik gjør du det - sjekk ut følgende kodeeksempel.

(function (global) {

    if(typeof (global) === "undefined") {
        throw new Error("window is undefined");
    }

    var _hash = "!";
    var noBackPlease = function () {
        global.location.href += "#";

        // Making sure we have the fruit available for juice (^__^)
        global.setTimeout(function () {
            global.location.href += "!";
        }, 50);
    };

    global.onhashchange = function () {
        if (global.location.hash !== _hash) {
            global.location.hash = _hash;
        }
    };

    global.onload = function () {
        noBackPlease();

        // Disables backspace on page except on input fields and textarea..
        document.body.onkeydown = function (e) {
            var elm = e.target.nodeName.toLowerCase();
            if (e.which === 8 && (elm !== 'input' && elm  !== 'textarea')) {
                e.preventDefault();
            }
            // Stopping the event bubbling up the DOM tree...
            e.stopPropagation();
        };
    }
})(window);

Dette er i ren JavaScript, så det vil fungere i de fleste nettlesere. Det vil også deaktivere backspace-tasten, men den tasten vil fungere normalt inne i input-felt og textarea.

Anbefalt oppsett:

Plasser denne koden i et eget skript og inkluder den på en side hvor du ønsker denne oppførselen. I den nåværende oppsettet vil den kjøre onload-hendelsen til DOM, som er det ideelle startpunktet for denne koden.

Fungerende DEMO!

Det ble testet og verifisert i følgende nettlesere,

  • Chrome.
  • Firefox.
  • Internet Explorer (8-11) og Edge.
  • Safari.

Svar #4

<script>
    window.location.hash = "no-back-button";

    // Again because Google Chrome doesn't insert
    // the first hash into the history
    window.location.hash = "Again-No-back-button"; 

    window.onhashchange = function(){
        window.location.hash = "no-back-button";
    }
</script>

Svar #5

For å begrense nettleserens tilbakehendelse:

window.history.pushState(null, "", window.location.href);
window.onpopstate = function () {
    window.history.pushState(null, "", window.location.href);
};

Svar #6

Hvordan blokkere funksjonalitet for å gå bakover:

history.pushState(null, null, location.href);
window.onpopstate = function () {
  history.go(1);
};

Svar #7

Denne koden vil deaktivere tilbake-knappen for moderne nettlesere som støtter HTML5 History API. Under normale omstendigheter går tilbake-knappen ett steg tilbake, til forrige side. Hvis du bruker history.pushState(), begynner du å legge til ekstra delsteg på den nåværende siden. Måten det fungerer på er, hvis du bruker history.pushState() tre ganger, og deretter begynner å trykke på tilbake-knappen, vil de første tre gangene navigere tilbake i disse delstegene, og deretter vil den fjerde gangen gå tilbake til forrige side.

Hvis du kombinerer denne oppførselen med en hendelseslytter på popstate-hendelsen, kan du i praksis sette opp en uendelig løkke av under-tilstander. Så, du laster siden, dytter en under-tilstand, og så trykker du på tilbake-knappen, som popper en under-tilstand og også dytter en annen, så hvis du trykker på tilbake-knappen igjen vil du aldri gå tom for under-tilstander å dytte. Hvis du føler at det er nødvendig å deaktivere tilbake-knappen, vil dette få deg dit.

history.pushState(null, null, 'no-back-button');
window.addEventListener('popstate', function(event) {
  history.pushState(null, null, 'no-back-button');
});

Svar #8

Ingen av de mest oppstemte svarene fungerte for meg i Chrome 79. Det ser ut til at Chrome endret oppførselen sin med hensyn til Tilbake-knappen etter versjon 75. Se her:

https://support.google.com/chrome/thread/8721521?hl=en

Men i den Google-tråden fungerte svaret som Azrulmukmin Azmi ga helt på slutten. Dette er hans løsning.

<script>
    history.pushState(null, document.title, location.href);
    history.back();
    history.forward();
    window.onpopstate = function () {
        history.go(1);
    };
</script>

Problemet med Chrome er at den ikke utløser onpopstate-hendelsen med mindre du utfører en nettleserhandling (dvs. kaller history.back). Derfor har jeg lagt til disse i skriptet.

Jeg forstår ikke helt hva han skrev, men tydeligvis kreves det nå en ekstra history.back()/history.forward() for å blokkere Tilbake i Chrome 75+.

Svar #9

Reager

For modal-komponenten i et React-prosjekt er å åpne eller å lukke modalen, og å kontrollere nettleserens tilbake-knapp, en nødvendig handling.

  • The stopBrowserBack: stopper funksjonaliteten til nettleserens tilbake-knapp, og får også en callback-funksjon. Denne callback-funksjonen er det du ønsker å gjøre:

    const stopBrowserBack = callback => {
      window.history.pushState(null, "", window.location.href);
      window.onpopstate = () => {
        window.history.pushState(null, "", window.location.href);
        callback();
      };
    };
    
  • startBrowserBack: gjenopplivingen av funksjonaliteten til tilbake-knappen i nettleseren:

    const startBrowserBack = () => {
      window.onpopstate = undefined;
      window.history.back();
    };
    

Bruken i prosjektet ditt:

handleOpenModal = () =>
  this.setState(
    { modalOpen: true },
    () => stopBrowserBack(this.handleCloseModal)
  );

handleCloseModal = () =>
  this.setState(
    { modalOpen: false },
    startBrowserBack
  );

Svar #10

Dette er måten jeg kunne fullføre det på.

Merkelig nok fungerte det ikke å endre window.location helt fint i Google Chrome og Safari.

Det hender at location.hash ikke oppretter en oppføring i historikken for Chrome og Safari. Så du må bruke pushstate.

Dette fungerer for meg i alle nettlesere.

history.pushState({ page: 1 }, "title 1", "#nbb");
window.onhashchange = function (event) {
    window.location.hash = "nbb";
};

Svar #11

history.pushState(null, null, document.URL);
window.addEventListener('popstate', function () {
    history.pushState(null, null, document.URL);
});

Denne JavaScript-koden tillater ikke at noen bruker går tilbake (fungerer i Chrome, Firefox, Internet Explorer og Edge).

Svar #12

Denne artikkelen på jordanhollinger.com er det beste alternativet, mener jeg. Ligner på Razors svar, men litt klarere. Kode nedenfor; full kreditt til Jordan Hollinger:

Side før:

<a href="/page-of-no-return.htm#no-back>You can't go back from the next page</a>

JavaScript for Page of no return:

// It works without the History API, but will clutter up the history
var history_api = typeof history.pushState !== 'undefined'

// The previous page asks that it not be returned to
if ( location.hash == '#no-back' ) {
  // Push "#no-back" onto the history, making it the most recent "page"
  if ( history_api ) history.pushState(null, '', '#stay')
  else location.hash = '#stay'

  // When the back button is pressed, it will harmlessly change the url
  // hash from "#stay" to "#no-back", which triggers this function
  window.onhashchange = function() {
    // User tried to go back; warn user, rinse and repeat
    if ( location.hash == '#no-back' ) {
      alert("You shall not pass!")
      if ( history_api ) history.pushState(null, '', '#stay')
      else location.hash = '#stay'
    }
  }
}

Svar #13

<html>
<head>
    <title>Disable Back Button in Browser - Online Demo</title>
    <style type="text/css">
        body, input {
            font-family: Calibri, Arial;
        }
    </style>
    <script type="text/javascript">
        window.history.forward();
        function noBack() {
            window.history.forward();
        }
    </script>
</head>
<body onload="noBack();" onpageshow="if (event.persisted) noBack();" onunload="">
    <H2>Demo</H2>
    <p>This page contains the code to avoid Back button.</p>
    <p>Click here to Goto <a href="noback.html">NoBack Page</a></p>
</body>
</html>

Relaterte artikler