質問: ユーザがクリックした場所が、テキストの上かそうでないかを判定するにはどうしたらよいでしょうか。 (テキストの上、というのはマウスカーソルが | になっている状態のことを考えています) 例えば、以下のコードでクリックした位置の「要素」を取得することはできました。 ``` document.addEventListener("mousedown", function(event){ console.log(event.target); }, true); ``` しかし、クリックしたのがテキストの上かどうかまで判別できませんでした。 event.target でテキストノード (#text) を取得できれば判別できそうでしたが、どうやっても などの要素 (Element) しか取得できませんでした。 できれば、クリックする対象のHTMLを変更しないで実現したいと考えています。 どうすればテキストの上かそうでないかを判定できるでしょうか?
回答: Rangeオブジェクトを利用すれば以下のように行単位、もしくは一文字単位で座標が取得できますので判定が可能です。 ``` // var element = document.getElementById('target'); // var e = window.event; // Rangeオブジェクトを作成する var range = document.createRange(); // 要素内のTextNodeについて繰り返し処理を行う for (var i = 0; i < element.childNodes.length; i++) { var n = element.childNodes[i]; if (n.nodeType == Node.TEXT_NODE) { // TextNodeのすべての文字を表す範囲を指定する var txt = n.textContent; range.setStart(n, 0); range.setEnd(n, txt.length); // TextNode内の各行の絶対座標を取得する。 var rects = range.getClientRects(); for (var j = 0; j < rects.length; j++) { var rect = rects[j]; // 各行について座標と範囲を判定する if (rect.left <= e.clientX && e.clientX <= rect.right && rect.top <= e.clientY && e.clientY <= rect.bottom) { alert('文字をクリックしました'); break; } } } } ```