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

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

ただいまの
回答率

90.40%

  • JavaScript

    18091questions

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

  • HTML

    9925questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • CSS

    6457questions

    CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

  • HTML5

    4444questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • CSS3

    2277questions

    CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

JavaScriptで、文字をクリックしたときにその文字の座標を得る方法はないでしょうか?

解決済

回答 2

投稿

  • 評価
  • クリップ 3
  • VIEW 3,493

odorry

score 45

div や span の中に設定された文字列の、任意の【文字】をクリックしたときに、その文字の座標を得る方法を調査しています。

例えば、以下のような HTML があったとして、この div 要素内の【さ】をクリックするなどして、
【さ】という文字の座業を取得したいのです。

<div>あいうえおかきくけこさしすせそたちつてとなにぬねの</div>
1文字1文字を div や span で囲めばできそうですが、それでは現実的ではないため、
特にそういった力任せなことはせずに取得できないものかなーと思っています。


論理的な手順としては、以下のように考えているのですが、手順3と手順6を実現する方法が具体的に思いつきません。

1.画面のどこかをクリックする

2.マウスでクリックした位置を保持しておく

3.その位置にある要素Xを取得する(*)

4.ある要素Xの位置を取得する

5.クリックした位置が、ある要素X内だとどの位置になるかを計算する

6.ある要素X内のクリックした位置に描画されている文字Yを取得する(*)

7.文字Yの画面全体での位置を取得する

8.目的達成


これに似た処理の実現を試みた方や、やり方そのものの方針のアイデアなどありましたら、
ご教示いただけると助かります。
よろしくお願いいたします。


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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

こちらの回答が参考になるかもしれません。

How to determine the position of a character in a div element?


5に関してはClickイベントでoffsetXやpageXやScreenXを使えば求められそうな気がします。

7に関してどの程度の精度が必要かわかりませんがそのままClickイベントでpageXなどではだめなんでしょうか?

もし文字の左上の座標を求める場合は折り返しもあるので大変じゃないかと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2014/08/25 02:07

    flied_onion さん、ご回答ありがとうございます。

    >もし文字の左上の座標を求める場合は折り返しもあるので大変じゃないかと思います。

    はい、大変だと思っています。
    また、おそらく実現するのは難しいのでは?と現状では思っていることに
    挑戦しているという状況です。

    さて、ご回答いただきました参考ページですが、
    残念ながら、直接的には目的の達成までには至りませんでした。
    ただ、Selection を使うというところから、【矩形を取得する】
    というアプローチのアイデアが発生し、以下のページに辿り着きました。

    JavaScriptで文字列の矩形領域を取得する
    http://mattatz.hatenablog.jp/entry/2013/07/21/155545

    このページに書かれている方法で、【各文字の絶対位置】を取得し、
    画面をクリックした場所が【どの矩形に含まれるか】を判定し、
    結果的に、その矩形と同じ場所に同じ大きさの div 要素を絶対的に配置することで、
    【要素になっていない文字単体を選択したかのような効果】を表現することができました。

    質問の方で書かせていただいた、

    <div>あいうえおかきくけこさしすせそたちつてとなにぬねの</div>

    の場合の【さ】の部分だけ、色を変更することができました、ということです。
    ※色を変更と言っても、重ねて div 要素の四角形を配置しているだけです


    Selection → 矩形 → Range オブジェクトと辿ることができ、
    【文字の座標を得る】というところまで行けましたので、
    この質問に対しては十分解決できたと思っています。


    すこし長くなりますが・・・、

    実は、この質問は、もっと別の問題を解決するための第一段階なのです。
    真に実現したいことは、【任意の位置に吹き出し画像のような物を設置】し、
    その設置した要素が、折り返しなどが発生しても、きちんと追従する、
    ということが実現できるかどうか、ということです。
    ですので、まずは、設置場所を単なる絶対座標ではなく、
    【ある文字の上に置いた】というようなことができれば追従できるかもしれないと
    考え、このような質問をさせていただきました。

    具体的にどういうことかと言いますと、
    上記の div 要素の例で、【さ】の部分に吹き出し画像の吹き出し開始部分が
    設置されたとして、折り返しや文字サイズの変更が行われても、【さ】の部分から
    吹き出しの開始部分が設置されていることをキープする、ということを
    目指しています。

    単純に position: absolute で、x, y 座標を指定して設置してしまうのは当然 NG でして、
    position: absolute で、x, y 座標を em で指定すると、かなり要件に近い状態で実現はできます。が、この場合、【折り返し】で破綻してしまいます。
    ※【折り返し】がなければ、この em 指定が落とし所かな、と思っています。

    【折り返し】をしても問題ない、ということを実現するのは
    かなり厳しいとは思いますが、簡単に「できない」と結論付けたくないと考えています。


    長くなりましたが、以上となります。


    キャンセル

0

簡単に作った例ですのでブラウザごとの実装についてわかりかねますが以下のようなものはどうでしょうか?
またソースが汚いことをお許しください。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Compliance</title>
    </head>
    <body>
    <style>
        #wrapper{
            width : 100%;
            height : auto;
            margin : 0px;
            padding : 10px;
        }
        #contents {
            width : 100%;
            height : auto;
            margin : 0px auto;
            padding : 0px;
        }
        #compliance_wrapper {/*--追従させるマーカーの役割--*/
            width : 0px;
            height : 0px;
            margin : 0px;
            padding : 0px;
        }
        #compliance {/*--追従させる要素--*/
            width : 1em;
            height : 1em;
            margin : 0px;
            padding : 0px;
            position : absolute;
            background : #CCCCCC;
            display : inline-block;
            z-index : 9999;
        }
    </style>
    <div id="wrapper">
        <div id="contents">
            あいうえおかきくけこさしすせそなにぬねの<span id="compliance_wrapper">は</span>ひふへほまみむめもやゆよらりるれろわをん
        </div>
    </div>
    <span id="compliance">○</span><!--追従させる要素-->
    
    <script>
        /*--ここではとりあえず座標が変わっても追従させるためsetIntervalを使用していますが目的に合わせ変更してください--*/
        (function (){
            var ComplianceElement=document.getElementById("compliance");
            function Compliance(){
                var _Bounds=document.getElementById("compliance_wrapper").getBoundingClientRect();
                ComplianceElement.style.top=_Bounds.y-15+"px";
                ComplianceElement.style.left=_Bounds.x+"px";
            };
            setInterval(Compliance,1000/60);
        }());
    </script>
    </body>
</html>
質問者の方が作成しようとしているのはこのような動作の物ですかね?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/01/24 20:21

    コードありがとうございます。
    コードを見てなるほどなるほど、と思いました。
    そうです。こういう動作のものです。

    ただ、Mac の Chrome or Safari でそのままでは動かなかったので、
    少し修正して狙っているものができました。

    最終的な目標を具体に言うと、HTML で作られた画面上に、吹き出しを任意の位置に設置し、画面のウィンドウサイズを変更させて折り返しが発生しても、吹き出しの位置が変わらないようにしたかったのです。

    そのために、

    1.クリックした任意の文字の位置を取得する
    2.折り返しが発生しても位置追跡する

    という2点をクリアしたかったのです。

    コードでいただいた【<span id="compliance_wrapper">は</span>】この部分が、
    任意の文字をクリックしたときに挿入できれば実現ができそうです。

    かなり良いヒントになりました。
    ありがとうございました!

    キャンセル

  • 2015/01/24 22:07

    http://mattatz.hatenablog.jp/entry/2013/07/21/155545
    JavaScriptで文字列の矩形領域を取得する



    https://teratail.com/questions/3263
    の二つを合わせるとよさそうですね

    キャンセル

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

  • JavaScript

    18091questions

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

  • HTML

    9925questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • CSS

    6457questions

    CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

  • HTML5

    4444questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • CSS3

    2277questions

    CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。