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

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

ただいまの
回答率

90.00%

【JavaScript】マウス操作イベントの練習プログラム

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,238

himejiy3

score 73

16個x16個の白枠ブロック上で、マウスドラッグしながらなぞると黒いブロックが置かれる・・
という単純なプログラムを組みたかっただけなのですが、つまづいてしまいました。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>マウスイベントの練習</title>
</head>
<body>
<div id="canvas">
</div>
<script src="main.js"></script>
</body>
</html>
document.addEventListener("DOMContentLoaded", () => {
  "use strict";

  const canvas = document.getElementById("canvas");

  const BLOCK_WIDTH = 10;  // png画像は縦横10ピクセル
  const BLOCK_HEIGHT = 10;
  const BOX_WIDTH = 16;  // 並べる個数
  const BOX_HEIGHT = 16;
  const BLOCKpng = "block.png";
  const BLACKpng = "black.png";

  let mousBtnFlag = false;

  let x, y;
  let n = 1;  // 左上がsquare1
  const blockFlg = document.createDocumentFragment();
  for (y = 1; y <= BOX_HEIGHT; y++) {
    for (x = 1; x <= BOX_WIDTH; x++) {
      const img = document.createElement("img");
      img.id = `square${n}`;
      img.src = BLOCKpng;
      img.style.position = "absolute";
      img.style.left = `${x * BLOCK_WIDTH}px`;
      img.style.top = `${y * BLOCK_HEIGHT}px`;
      blockFlg.appendChild(img);
      n++;
    }
  }
  canvas.appendChild(blockFlg);

  // 関数--------------------
  function mousDown() {
    mousBtnFlag = true;
  }
  function mousUp() {
    mousBtnFlag = false;
  }

  function mousMove(event) {
    if (mousBtnFlag) {
      event.src = BLACKpng;
    }
  }

  // イベント処理----------------
  let i;
  for (i = 1; i < n; i++) {
    const obj = document.getElementById(`square${i}`);
    obj.addEventListener("mousemove", () => {
      mousMove(obj);
    });
    obj.addEventListener("mouseup", () => {
      mousUp();
    });
    obj.addEventListener("mousedown", () => {
      mousDown();
    });
  }

});

マウス左ボタンを押し続けている間は
mousBtnFlag が true として、
mousemove と フラグtrueが両方成り立つ時に黒ブロックを置いていく・・

と書いたつもりですが、思惑通りには動いてくれませんでした。

いろいろイジって、思惑に最も近付いたコードが上記です。
しかしこれ以上はギブアップ気味です・・。ご教授よろしくお願いいたします。

Chromeで動いてくれればOKです。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+3

うまく動かないというのはおそらく画像がドラッグ状態になることかと思います。

obj.addEventListener("mousedown", (e) => {
  mousDown();
  e.preventDefault(); // ドラッグにならないようここでキャンセル
});


jsFiddleであなたのコードをもとに動作サンプルを作りました。
https://jsfiddle.net/ofd3gxmn/

なお、このコードだとcanvasの外でマウスを離すとmousBtnFlagがtrueのままになってしまうので、その対処は別でやる必要があります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/11 10:01

    おー、動きました!これです!こう動いてほしかったんです!
    イベントの伝播に原因があったんですね…。この解決法は自分1人では辿り着かなかったと思います。
    ありがとうございました。大変勉強になりました。

    キャンセル

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

  • ただいまの回答率 90.00%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる