7

JavaScriptでマインスイーパを作ろうとしていて、この問題に遭遇しました...

私はテーブルを作成しました。各 td は、鉱山または何もない (現在) 「ボックス」です。ボックスをクリックした後、JavaScript は onclick を "clicked(this.id)" から "NOPE" というアラートに変更する必要があります (何かが起こっているかどうかをテストするためだけにアラートを作成しました)。

  1. 「ボックス1」をクリックすると、そこにあるもの(爆弾か何もないか)が表示されます
  2. もう一度クリックすると、今度はアラート「NOPE」が表示されます。これは、onclickが変更されたことを意味します。良い!
  3. 「ボックス 2」をクリックすると、そこに何があるか (爆弾か何もないか) が表示されます
  4. もう一度クリックすると、今度は「NOPE」というアラートが表示されます。これは、この onclick も変更されたことを意味します。
  5. 「ボックス1」をもう一度クリックします。clicked(this.id) が再び実行されます。(これは、関数が実行されるたびにカウンターを追加したために表示されます)

何らかの理由で、onclick が元の値 (clicked(this.id)) に戻ります。

私はテストページ、2つのtdを持つテーブルを作成し、同じ考えを念頭に置いて(クリック後にonclick値を変更する)、動作します..これを修正する方法がわかりません...

動作する test.html: http://pastebin.com/62ayRJps

意図したとおりに機能しないサイトの HTML: http://pastebin.com/SZ6NU8j9

そして、意図したとおりに機能しないサイトの Javascript: http://pastebin.com/bevJHNLc

4

3 に答える 3

4

の次の行が原因で、クリック イベント ハンドラがリセットされていますclicked(id):

document.getElementById("minesweeper").innerHTML += ammountClicked+" - "

各テーブル セルのonclick='clicked(this.id);'HTML には属性があります。テスト関数tstをテーブル セルの DOM オブジェクトに割り当てると、DOM オブジェクトのプロパティが設定されますが、HTMLonclickの属性は変更されません。onclick(はい、紛らわしいです。)

上記のコード行では、ブラウザーは(元の属性を持つ) マインスイーパinnerHTMLから を読み取り、それを別の文字列と連結してから、結果をマインスイーパに再割り当てします。これにより、 の元のコンテンツが消去され、新しい HTML (すべてのセルが元の属性を持つテーブル) に置き換えられます。divonclickdivdivonclick


メッセージ領域が必要な場合は、innerHTML別の要素を設定することをお勧めします: Demo

デモでは、49行目を変更しました( を追加span):

print += "</table><span id='message'></span>";

および 107 行目 (テキストを に割り当てますspan):

document.getElementById("message").innerHTML += ammountClicked+" - ";
于 2013-02-04T16:20:38.583 に答える
1

各アイテムの状態を追跡することをお勧めします。アプリケーションの実行中にコードを変更しないことをお勧めします。

var states = {1: 0, 2: 0};

function clicked(id)
{
    if (states[id] === 0)
      alert("First time clicking me, eh?");
    else
      alert("Seems we have a repeat offender!");

    states[id]++;
}

stateこれにより、特定ののidが変更されているかどうかを確認することで(たとえば、前のクリックによって)、 関数内のロジックを分割できます。

jsbinのインタラクティブデモ
于 2013-02-03T12:00:42.337 に答える
0

いくつかの変更を加えると、次のfunction clicked(id)ように機能します。

  1. コメント行//document.getElementById(id).onclick = tst;
  2. field[row][column] = false;関数の最後に追加
  3. falseアクションを実行する前に、フィールドに含まれているかどうかを確認します。

    if (field[row][column] == false) {
        console.log("This cell has already been clicked");
        return;
    }
    

onclick イベントを変更する必要はありません。

Jeffery Toが説明した問題は次のとおりです。

  1. セル0,0をクリックします
  2. 関数clickedが呼び出されます
  3. minesweeper.innerHTML = minesweeper.innerHTML + "1 - "[すべての onclick イベントがリセットされました]
  4. セル0,0のonclickイベントを変更
  5. たとえば、 0,1などの新しいセルをクリックします。
  6. minesweeper.innerHTML = minesweeper.innerHTML + "2 - "[すべての onclick イベントがリセットされました]
  7. セル0,1の onclick イベントが変更されます

innerHTML にすべての onclick 宣言が含まれているため、onclick イベントはリセットされます。これは、その div のすべての HTML を書き換えて、すべての子要素とそのイベントを書き換えるようなものです。これが、単純な例 (セルが 2 つしかない例) が機能する理由でもあります。

于 2013-02-06T09:36:58.513 に答える