質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • JavaScript

    20429questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

【javascript】配列内の要素の操作

受付中

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 322

stalin

score 1

前提・実現したいこと

配列内の要素がクリックされた時に、その要素に画像を表示したい

発生している問題・エラーメッセージ

マインスイーパーを練習で作っています。試験的に9マスで作っています。
9マスをシャッフルして、3,4番目を取り出すことでランダムに爆弾の位置を二箇所決定しています。
爆弾の配列[bom]内の要素がクリックされた時にその要素の上に、爆弾の画像を表示させたいのですが、どうしたらいいでしょうか?
該当のソースコードで試したらCannot set property 'onclick' of nullというエラーが出ました。

該当のソースコード

[HTML]
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;
    charset=shift_jis" http-equiv"Content=Type" />
<title></title>
<link rel="stylesheet" type="text/css" href="背景など.css">
</head>
<body>
<h1>マインスイーパーランダム</h1>
<table id="field">
<tr>
<td></td><td></td><td></td>
</tr>
<tr>
<td></td><td></td><td></td>
</tr>
<tr>
<td></td><td></td><td></td>
</tr>
</table>
<script src="moving.js"></script>
</body>
</html>
[js]

//ますの要素をまとめて指定
var arr = Array.from(document.getElementsByTagName('td'));
var a = arr.length;

//シャッフルアルゴリズム
while (a) {
    var j = Math.floor( Math.random() * a );
    var t = arr[--a];
    arr[a] = arr[j];
    arr[j] = t;
}
//3,4番目を指定して分ける
const bom = arr.splice(3,2);
console.log(arr);
console.log(bom);

document.getElementById(bom).onclick = function() {
document.getElementById(bom).innerHTML = "img/bom1.jpg";
}
[css]
body {
  background-color: #263238;
}

h1 {
  color: #FFFFFF;
}

table {
  width: 400px; 
  height: 400px;
  margin-left: auto;
  margin-right: auto;
}

td {
  width: 10%;
  height: 10%;
  background-color: #455A64;

補足情報

google chrome(バージョン: 72.0.3626.96(Official Build))で動作テストしています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2019/02/14 01:19

    (質問文は編集できます)質問文のコードはそれぞれコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。また、「発生している問題」の部分はコードでないので、コードブロックで囲む必要はありません。
    また、ご自身で試されたコードを質問文に追記し、「何」が「どのように」わからないのか、コードのどの部分で詰まっているのかなどを具体的に追記されたほうが回答が望めると思います。

    キャンセル

回答 4

+3

もし100x100マスのテーブルで作るとなったとき、現状では10000個のイベントをつけることになるのだから根本から考え直したほうがよい。
アドバイスするならそこからだろう?

<!DOCTYPE html>
<title>?</title>
<meta charset="utf-8">
<style>
</style>

<body>
<table border="1"></table>

<script>

let a = Array (20).fill().map ((a,b) => Array (20).fill ().map ((c,d)=> `${d},${b}`));
let t = document.querySelector ('table');
a.forEach(function(b){b.forEach(function(c){this.insertCell().textContent=c},this.insertRow())},t);

t.addEventListener ('click', e=> {
  let {textContent: t, cellIndex: x, parentNode:{rowIndex: y}} = e.target;
  alert(`座標は(${x},${y})、値は \"${t}\" です`);
},false);

</script>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

HTMLでid名は2つ宣言できません。
またdocument.getElementById()の引数はクォーテーションで囲む必要があります。

  var arr = Array.from(document.getElementsByTagName('td'));
  var a = arr.length;

  //シャッフルアルゴリズム
  while (a) {
    var j = Math.floor( Math.random() * a );//ランダムな数字
    var t = arr[--a]; //
    arr[a] = arr[j];
    arr[j] = t;
  }

  const bom = arr.splice(3,2);
  const classVal = "bom";

  for (var i = 0; i < bom.length; i++) {
    bom[i].setAttribute('class', classVal);
    bom[i].addEventListener('click', function(e) {
      this.innerText = "Bom!!!!!";//ここを適宜変更してください。
    });
  }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/14 08:29

    ネイティブなので、クラスを追加する時、setAttributeではなく、
    bom[i].classList.add(classVal);
    でもいいかもしれませんね。

    キャンセル

0

配列変数bomには、DOM要素が直接入っている状態なので、
document.getElementById(bom)では、要素を取得できません。
document.getElementById()メソッドは、
<div id="hoge"></div>など、id属性に指定した文字列を引数に渡し、該当のDOMを返すというメソッドです。
(document.getElementById('hoge') というように使う)

よって、下記のように、bomの要素一個一個にアクセスするとよいでしょう。

// メモリ消費を防ぐために関数を先に定義
var clickFunc = function(){
  this.innerHTML = '<img src="img/bom1.jpg">';
};

// 配列の全要素にforEachでアクセス、DOMに対して、onclickイベントを付与
bom.forEach(function(val){
  val.onclick = clickFunc;
});

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/14 10:02

    .call(val)って必要ですか?つけるとその場で実行しませんか?

    キャンセル

  • 2019/02/14 10:27

    ご指摘ありがとうございます。
    いけますね・・・。
    val.onclick = function(){ val.innerHTML = '<img src="img/bom1.jpg">'; }
    でいいですよね 汗
    回答修正します。

    キャンセル

  • 2019/02/14 10:29

    val.onclick = clickFunc;で問題ないですよ。

    キャンセル

  • 2019/02/14 10:30

    ご指摘ありがとうございます!

    キャンセル

  • 2019/02/14 10:33

    そうでした、onclickさせた時、処理元のthisで要素自体を取得できるんでした。
    ご指摘ありがとうございます。

    キャンセル

0

ざっくりこんな感じ

<style>
.bom{color:red} /* これを消すとbomの位置がわからなくなる*/
</style>
<script>
document.addEventListener('click', function(e){
  var t=e.target;
  if(t.nodeName=="TD"){
    if(t.classList.contains('bom')){
      alert('bom');
    }else if(t.classList.contains('safe') && !t.classList.contains('open')){
      t.classList.add('open');
      t.textContent="□";
      if(document.querySelectorAll('.safe').length==document.querySelectorAll('.open').length){
        alert('complete');
      }
    }
  }
});
window.addEventListener('DOMContentLoaded', function(e){
  var td = document.querySelectorAll('td');
  [].forEach.call(td,function(x){
    x.classList.add('safe');
  });
  var a=Array(td.length).fill(null).map(function(x,y){
    return [y,Math.random()];
  });
  a.sort(function(x,y){
    return x[1]-y[1];
  });
  var boms=2;
  Array(boms).fill(null).forEach(function(x,y){
    with(td[a[y][0]]){
      classList.remove('safe');
      classList.add('bom');
    }
  });
});
</script>
<table>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • JavaScript

    20429questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。