JavaScriptで、文字をクリックしたときにその文字の座標を得る方法はないでしょうか?
解決済
回答 2
投稿
- 評価
- クリップ 3
- VIEW 5,525
例えば、以下のような 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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
How to determine the position of a character in a div element?
5に関してはClickイベントでoffsetXやpageXやScreenXを使えば求められそうな気がします。
7に関してどの程度の精度が必要かわかりませんがそのままClickイベントでpageXなどではだめなんでしょうか?
もし文字の左上の座標を求める場合は折り返しもあるので大変じゃないかと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
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>
質問者の方が作成しようとしているのはこのような動作の物ですかね?投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.20%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2014/08/25 02:07
>もし文字の左上の座標を求める場合は折り返しもあるので大変じゃないかと思います。
はい、大変だと思っています。
また、おそらく実現するのは難しいのでは?と現状では思っていることに
挑戦しているという状況です。
さて、ご回答いただきました参考ページですが、
残念ながら、直接的には目的の達成までには至りませんでした。
ただ、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 指定が落とし所かな、と思っています。
【折り返し】をしても問題ない、ということを実現するのは
かなり厳しいとは思いますが、簡単に「できない」と結論付けたくないと考えています。
長くなりましたが、以上となります。