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

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

ただいまの
回答率

89.53%

JavaScript 画像上のクリックした指定座標にマークを付けるには

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 8,560

DgRp_08

score 54

イメージ説明仕様として、DBから画像ファイルパスを取得後、それを利用して複数の画像を一つの画面に表示させます。

画像表示エリアは一つ一つ高さと幅が決められており、画像は見切れるのでoverflow scrollが設定されます。

その画像に対して、クリックした箇所にマークを付ける機能を実装したいです。
マークの付いた箇所の座標はDBへ保存され、他のページであっても画像上の同一座標にマークが表示されるような機能です。

画像上での座標の取得は分かったのですが、それを利用してマークを付ける処理が分かりません。単純に取得座標を設定しても座標の基準ポイントがウィンドウになってしまうので画像上の座標になりません。

端的に言うといつでもどこでも各画像とマークはセット。各画像の左上が基準の座標をマーク表示箇所として指定したい。ということです。
よって、ウィンドウ左上を基準として、誤差を加算するという手法が使えません。

JavaScriptでどのような処理をしたら良いでしょうか?
また、ブラウザがIE7なのであまり新しい技術は使えません。

ご教示宜しくお願い致します。
スペルミスや大文字小文字のミスはスルーして下さい。

【現在上手く行っていない実装】
※サンプルなのでDBなどは考慮せず、また、画像は一つでしか試してません。

<script type="text/javascript">
  var count;
  function SetMark(x,y){
    count++;
    var element = document.createElement('p');
    element.id = "id" + count;
    element.innnerHTML = "●";
    element.style.position = "absolute";
    element.style.left = x + "px";
    element.style.top = y + "px";
    var obj = document.getElementById("imgArea");
    obj.appendChild(element);
  }
</script>
<body>
  <div id="imgArea" style="width:500px; height:300px; overflow-x:scroll; overflow-y:scroll">
    <img src="img.jpg" style="width:800px; height:500px;" onclick="SetMark(event.offsetX,event.offsetY)">
  </div>
</body>


【追記】
参考として仕様のイメージ画像を添付しました。
添付画像の画像1、画像2と登録されている分だけ画像が表示されます。
例として画像1の左側部分をクリックしてマークをつけた場合、その画像上の座標情報はDBに保存され、他のweb画面だろうが、画像の位置が少し変わっていようが、画像1という画像には左側部分のあくまで「画像上の固定された座標」にマークが記されます。
グーグルマップのようなイメージです。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

やり方としては基本的に下記サイトのような感じで、かつ addEventListener のかわりに attachEvent を使うことで IE7とか言う魔物にもわかるコードになると思われます。

【JavaScriptでマウスの位置座標を取得する方法】
https://syncer.jp/javascript-reverse-reference/get-mouse-position

【EventTarget.addEventListener - Web API インターフェイス | MDN】
https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener

// マウスイベントを設定
element.attachEvent( "onclick", function( e ) {
    // マウス位置を取得する
    var mouseX = e.pageX ;    // X座標
    var mouseY = e.pageY ;    // Y座標

    // 要素の位置を取得
    var elem = e.target || e.srcElement || window.event.target || window.event.srcElement || element;
    var rect = elem .getBoundingClientRect() ;

    // 要素の位置座標を計算
    var positionX = rect.left + window.pageXOffset ;    // 要素のX座標
    var positionY = rect.top + window.pageYOffset ;    // 要素のY座標

    // 要素の左上からの距離を計算
    var offsetX = mouseX - positionX ;
    var offsetY = mouseY - positionY ;

} ) ; // 環境が用意できないため未テスト


【javascript - Get the caller of the event from attachEvent - Stack Overflow】
http://stackoverflow.com/questions/11524762/get-the-caller-of-the-event-from-attachevent

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/06/02 03:11

    回答有り難うございます。

    すみません、初心者で解読がスムーズにできず、上手くサンプルに組み込めません。
    『element.attachEvent( "onclick", function( e )』の部分の『element』はどの要素のことなのでしょうか。質問記載のサンプルと切り離すべき内容なのか、連携すべき内容なのかさえ判断ができておりません。。

    あと、座標の取得だけの処理のように見えますが、マークを付ける時は「offsetX/offsetY」の座標を指定すればいいということでしょうか?

    また、画像を画面に表示する時、その画面の左上だろうが真ん中だろうが右下だろうが、一度付けたマークは 一度取得した「offsetX/offsetY」さえ指定すれば画像上では絶対に同じ位置にマークが付いてくれるという認識で大丈夫でしょうか。

    上手く解釈もできず試しもできず申し訳ありませんが教えていただけると助かります。
    宜しくお願い致します。

    キャンセル

  • 2016/06/02 19:46

    > 『element.attachEvent( "onclick", function( e )』の部分の『element』はどの要素のことなのでしょうか。
    elementはimg要素です。たくさんの画像が有るページであれば取得方法を考える必要があったので、手を抜きました。

    > 座標の取得だけの処理のように見えます
    画像上の座標取得部分がわからないものだと思ったのでそこを書いたつもりです。要素(pなど)を固定の位置に置くのであればimg要素を包む要素に「position: relative;」を付ける必要があります。

    > マークを付ける時は「offsetX/offsetY」の座標を指定すればいいということでしょうか?
    今質問文を見た所、画像の置かれているのがスクロールが発生する要素の中なので、そのスクロール分も計算する必要があります。

    【スクロール量を取得する-JavaScript入門】
    http://www.pori2.net/js/window/9.html

    【[JavaScript] スクロール量の取得 - JavaScript でどのくらいスクロールしたかを取得する】
    https://www.ipentec.com/document/document.aspx?page=javascript-scroll

    【Element.scrollLeft - Web APIs | MDN】
    https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
    【Element.scrollTop - Web APIs | MDN】
    https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop


    > また、画像を画面に表示する時、その画面の左上だろうが真ん中だろうが右下だろうが、一度付けたマークは 一度取得した「offsetX/offsetY」さえ指定すれば画像上では絶対に同じ位置にマークが付いてくれるという認識で大丈夫でしょうか。
    だめです。回答に書かれた内容は「画像の中の左上からの位置」についてを取得しているだけです。
    たとえば画像が左から10pxの位置にある場合、画像の左端をクリックしたら「0」が取得できるといった感じです。

    また、「初心者」であるならIE7などではなく最新ブラウザを導入してまずはクリック座標について学ぶのをお勧めします。FirefoxであればWinXP/VISTAも対応しています。

    【Firefox - 46.0.1 System Requirements - Mozilla】
    https://www.mozilla.org/en-US/firefox/46.0.1/system-requirements/

    キャンセル

  • 2016/06/03 02:09

    ご説明ありがとうございます。
    お手数おかけして申し訳ありません。

    私の考え方がズレていたせいで解釈に誤差が生じまくったようです。。

    質問文記載のコード内の「event.offsetX」等でクリック箇所の「画像上の座標」自体は既に取得できていたので、「座標の取得は完了した。この座標を使ってマーク付けるのどうしたらいいんだ?」と分割して考えていたので、座標を取得したのに意味が無いという状態でした。…と申し上げても正しく伝わらないと思いますが、私はいわゆるPGに関して勘の悪いタイプなので、ご容赦ください。

    とりあえず教えていただいた処理の流れに関しては一体どういうことだったのかイメージを掴むことが出来たのでなんとかなりそうです。

    ブラウザに関してはChromeやIE、Firefoxなどの最新環境については自前で整っていますが、IE7使用というのは好みではなく仕事で客先の本番環境なのでどうすることもできません。

    丁寧に教えていただいて本当にありがとうございました。

    キャンセル

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

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