212

PHPでオンラインクイズアプリケーションをやっています。ユーザーが試験に戻ることを制限したい。

次のスクリプトを試しましたが、タイマーが停止します。

私は何をすべきか?

タイマーはファイルcdtimer.jsに保存されます。

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

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

MySQL の値から試験の期間を取る試験タイマーがあります。それに応じてタイマーが開始されますが、戻るボタンを無効にするコードを挿入すると停止します。私の問題は何ですか?

4

35 に答える 35

183

戻るボタンを無効にしても実際には機能しない理由はたくさんあります。最善の策は、ユーザーに警告することです。

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

このページには、戻るボタンを無効にする方法がいくつかリストされていますが、保証されているものはありません

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

于 2012-09-12T05:15:51.120 に答える
152

一般に、Webブラウザのデフォルトの動作を上書きすることはお勧めできません。クライアント側のスクリプトには、セキュリティ上の理由から、これを行うための十分な権限がありません。

同様の質問がいくつかありますが、

ブラウザの戻るボタンを実際に無効にすることはできません。ただし、ロジックを使用して魔法をかけることで、ユーザーが戻って、無効になっているような印象を与えるのを防ぐことができます。方法は次のとおりです。次のスニペットを確認してください。

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

これは純粋なJavaScriptであるため、ほとんどのブラウザーで機能します。また、バックスペースキーを無効にしますが、そのキーはinputフィールドと内で正常に機能しますtextarea

推奨されるセットアップ:

このスニペットを別のスクリプトに配置し、この動作が必要なページに含めます。現在のセットアップでonloadは、このコードの理想的なエントリポイントであるDOMのイベントを実行します。

ワーキングデモ!

次のブラウザでテストおよび検証されました。

  • クロム。
  • Firefox。
  • Internet Explorer(8-11)およびEdge。
  • サファリ。
于 2012-09-12T05:45:40.193 に答える
128

私はこれに遭遇し、 Mobile Safari (投稿時の iOS 9)を含むさまざまなブラウザーで正しく「うまく」機能するソリューションを必要としていました。どの解決策もまったく適切ではありませんでした。以下を提供します (Internet Explorer 11、Firefox、Chrome、および Safari でテスト済み):

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

次の点に注意してください。

  • history.forward()(私の古いソリューション) は Mobile Safari では機能しません --- 何もしていないようです (つまり、ユーザーはまだ戻ることができます)。history.pushState()それらのすべてで動作します。
  • の 3 番目の引数history.pushState()urlです。'no-back-button'次のような文字列を渡すか、正常に動作するように見えるソリューション'pagename'は、ページで更新/再読み込みを試みるまで、ブラウザがそれを URL として使用してページを見つけようとすると、「ページが見つかりません」というエラーが生成されます。(ブラウザは、ページ上にあるときにその文字列をアドレス バーに含める可能性も高く、これは醜いです。)location.hrefを URL に使用する必要があります。
  • の 2 番目の引数history.pushState()titleです。Web を見回すと、ほとんどの場所で「使用されていません」と表示されており、ここにあるすべてのソリューションはそれに合格nullしています。ただし、少なくとも Mobile Safari では、ページの URL がユーザーがアクセスできる履歴ドロップダウンに入れられます。しかし、通常、ページ訪問のエントリを追加すると、そのタイトルに入れられます。これは望ましいことです。したがって、それを渡すdocument.titleと、同じ動作になります。
于 2015-12-17T14:57:05.457 に答える
26

逆方向の機能をブロックする方法:

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

于 2016-11-24T13:50:26.697 に答える
19

Chrome 79では、最も支持された回答はどれもうまくいきませんでした。バージョン 75 以降、[戻る] ボタンに関する Chrome の動作が変更されたようです。こちらを参照してください。

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

ただし、そのGoogleスレッドでは、最後にAzrulmukmin Azmiが提供した回答が機能しました. これが彼の解決策です。

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

Chrome の問題は、ブラウザのアクション (つまり、history.back を呼び出す) を行わない限り、onpopstate イベントがトリガーされないことです。そのため、それらをスクリプトに追加しました。

彼が何を書いたかは完全には理解できませんがhistory.back() / history.forward()、Chrome 75+ で Back をブロックするには追加が必要になったようです。

于 2020-01-27T17:08:11.857 に答える
13

これが私がそれを達成できる方法です。

奇妙なことに、 window.locationを変更しても、Google Chrome と Safari ではうまくいきませんでした。

location.hashが Chrome と Safari の履歴にエントリを作成しないことがあります。したがって、プッシュステートを使用する必要があります。

これは、すべてのブラウザで機能しています。

history.pushState({ page: 1 }, "title 1", "#nbb");
window.onhashchange = function (event) {
    window.location.hash = "nbb";
};
于 2013-12-24T17:07:33.253 に答える
10

jordanhollinger.comのこの記事は、私が感じる最良の選択肢です。Razorの答えに似ていますが、少し明確です。以下のコード; ジョーダンホリンガーへの完全なクレジット:

前のページ:

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

ノーリターンのJavaScriptのページ:

// 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'
    }
  }
}
于 2013-02-15T12:49:24.037 に答える
10
<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>
于 2013-06-18T18:20:24.290 に答える
2

これは、ブラウザの戻るボタンと、戻るためのバックスペース ボタンを無効にするのに有効だったようです。

history.pushState(null, null, $(location).attr('href'));
window.addEventListener('popstate', function () {
    history.pushState(null, null, $(location).attr('href'));
});
于 2015-11-12T19:28:00.090 に答える
0

1 つの HTML ページ ( index.html ) を作成します。また、スクリプトフォルダー/ディレクトリ内に 1 つ ( mechanism.js ) を作成します。次に、必要に応じてフォーム、テーブル、スパン、および div タグを使用して、すべてのコンテンツを ( index.html ) 内に配置します。では、戻る/進むを何もしないようにするトリックを次に示します。

まず、ページが 1 つしかないという事実です。第二に、通常のリンクを介して必要なときに同じページのコンテンツを非表示および表示するための、span / div タグを含む JavaScript の使用!

「index.html」内:

<td width="89px" align="right" valign="top" style="letter-spacing:1px;">
    <small>
        <b>
            <a href="#" class="traff" onClick="DisplayInTrafficTable();">IN</a>&nbsp;
        </b>
    </small>
    [&nbsp;<span id="inCountSPN">0</span>&nbsp;]
</td>

「mechanism.js」内:

function DisplayInTrafficTable()
{
    var itmsCNT = 0;
    var dsplyIn = "";
    for (i=0; i<inTraffic.length; i++)
    {
        dsplyIn += "<tr><td width='11'></td><td align='right'>" + (++itmsCNT) + "</td><td width='11'></td><td><b>" + inTraffic[i] + "</b></td><td width='11'></td><td>" + entryTimeArray[i] + "</td><td width='11'></td><td>" + entryDateArray[i] + "</td><td width='11'></td></tr>";
    }
    document.getElementById('inOutSPN').innerHTML =
        "" +
        "<table border='0' style='background:#fff;'><tr><th colspan='21' style='background:#feb;padding:11px;'><h3 style='margin-bottom:-1px;'>INCOMING TRAFFIC REPORT</h3>" +
        DateStamp() +
        "&nbsp;&nbsp;-&nbsp;&nbsp;<small><a href='#' style='letter-spacing:1px;' onclick='OpenPrintableIn();'>PRINT</a></small></th></tr><tr style='background:#eee;'><td></td><td><b>###</b></td><td></td><td><b>ID #</b></td><td></td><td width='79'><b>TYPE</b></td><td></td><td><b>FIRST</b></td><td></td><td><b>LAST</b></td><td></td><td><b>PLATE #</b></td><td></td><td><b>COMPANY</b></td><td></td><td><b>TIME</b></td><td></td><td><b>DATE</b></td><td></td><td><b>IN / OUT</b></td><td></td></tr>" +
        dsplyIn.toUpperCase() +
        "</table>" +
        "";
    return document.getElementById('inOutSPN').innerHTML;
}

わかりにくいかもしれませんが、関数名と呼び出し、埋め込まれた HTML、span タグ id の呼び出しに注意してください。これは、同じページの同じスパン タグに異なる HTML を挿入する方法を示すためのものでした。Back/Forward はこの設計にどのように影響しますか? オブジェクトを非表示にし、同じページで他のオブジェクトをすべて置き換えているため、できません!

どのように非表示にして表示することができますか? ここに行きます:

必要に応じて「 mechanism.js 」の関数内で、次を使用します。

document.getElementById('textOverPic').style.display = "none"; //hide
document.getElementById('textOverPic').style.display = "";     //display

' index.html ' 内で、リンクを介して関数を呼び出します。

<img src="images/someimage.jpg" alt="" />
<span class="textOverPic" id="textOverPic"></span>

<a href="#" style="color:#119;font-size:11px;text-decoration:none;letter-spacing:1px;" onclick="HiddenTextsManager(1);">Introduction</a>
于 2014-09-26T01:18:09.680 に答える
0

私の場合、これは買い物の注文でした。だから私はボタンを無効にしました。ユーザーがクリックして戻ると、ボタンは無効のままでした。もう一度クリックして戻り、次にページ ボタンをクリックして先に進んだとき。彼らの注文が送信され、別のページにスキップされたことを知っていました。

ページが実際に更新された場合、(理論的には) ボタンが使用可能になります。その後、ページの読み込みで、注文がすでに送信され、リダイレクトされていることに反応することができました。

于 2014-11-03T21:11:11.680 に答える
0

回答に基づく@Franklin Innocent F

Kotlin/JS (React) のソリューション:

import org.w3c.dom.events.Event
import kotlin.browser.document
import kotlin.browser.window

...
override fun componentDidMount() {
    window.history.pushState(null, "", window.location.href)
    window.history.back()
    window.history.forward()
    window.addEventListener("popstate", browserBackButtonHandler)
}

...
private val browserBackButtonHandler: (Event?) -> Unit = {
    window.history.go(1)
}
于 2022-01-17T09:03:49.750 に答える
0

ここでの解決策のいくつかは、バック イベントの発生を防止しません。バック イベントを発生させ (ブラウザのメモリに保持されているページに関するデータは失われます)、フォワード イベントを再生して、バック イベントが発生したという事実を隠そうとします。ちょうど起こったイベント。ページが一時的な状態を保持していた場合、これは失敗します。

vrfvrの回答に基づいて、React用にこのソリューションを作成しました(reactルーターが使用されていない場合)。

ユーザーがポップアップを確認しない限り、戻るボタンが何もしないようにします。

  const onHashChange = useCallback(() => {
    const confirm = window.confirm(
      'Warning - going back will cause you to loose unsaved data. Really go back?',
    );
    window.removeEventListener('hashchange', onHashChange);
    if (confirm) {
      setTimeout(() => {
        window.history.go(-1);
      }, 1);
    } else {
      window.location.hash = 'no-back';
      setTimeout(() => {
        window.addEventListener('hashchange', onHashChange);
      }, 1);
    }
  }, []);

  useEffect(() => {
    window.location.hash = 'no-back';
    setTimeout(() => {
      window.addEventListener('hashchange', onHashChange);
    }, 1);
    return () => {
      window.removeEventListener('hashchange', onHashChange);
    };
  }, []);
于 2020-10-21T11:08:51.847 に答える