5

I need to now where in a html block-element that contains only text a click happened:

<div>This is some awesome text</div>

I would like to get the position of the letter that was clicked. Limitation: it is not possible to add additional childs to the div.

Any options?

Dennis Guse
  • 883
  • 10
  • 34
  • You forgot to post the JavaScript you tried that didn't work. – j08691 May 23 '14 at 14:18
  • @j08691 I have not yet tried anything - I was wondering how to do this. And Google did not provide any results. In a mouseclick-handler I only get the position of the mouse and I know, which element emitted the event (in my case so far the div) - but still the exact position in relation to the text is still not known. – Dennis Guse May 23 '14 at 14:20
  • 1
    http://stackoverflow.com/a/12924488/96100 – Tim Down May 23 '14 at 15:59
  • @TimDown thanks for this solution - range is the way to go for me. And thanks for showing me _contenteditable_. – Dennis Guse May 25 '14 at 13:18

2 Answers2

11

Solution I adopted thanks to @TimDown is taken from Mozilla.

function insertBreakAtPoint(e) {

var range;
var textNode;
var offset;

if (document.caretPositionFromPoint) {    // standard
    range = document.caretPositionFromPoint(e.pageX, e.pageY);
    textNode = range.offsetNode;
    offset = range.offset;

} else if (document.caretRangeFromPoint) {    // WebKit
    range = document.caretRangeFromPoint(e.pageX, e.pageY);
    textNode = range.startContainer;
    offset = range.startOffset;
}

// do whatever you want here!
}

There is one limitation (at least I have a small problem in Chromium) that the range.textNode must not necessarily identical to the one that was clicked. The contained text might be shorter than expected. Reason for that remained unknown. I just did the access via range.textNode.parentElement.firstChild as in my case the div only has one child.

Dennis Guse
  • 883
  • 10
  • 34
  • There doesn't seem a way to get the position of a textNode at all with no mouse click – SuperUberDuper Aug 26 '16 at 17:20
  • thanks a lot, worked nicely I've found the following reference helpful as well: https://developer.mozilla.org/en-US/docs/Web/API/Document/caretRangeFromPoint – Neil Jan 19 '21 at 05:39
0

Subtract the offsets of the current element to get the position of the click relative to the element (fiddle):

$(function () {
    $("#awesome").click(function (event) {
      var div = $(this);  
      var posX = event.pageX - div.offset().left;
      var posY = event.pageY - div.offset().top;

      alert("X: " + posX + " Y: " + posY);
    });
});

You will have to do other calculations to figure out which letter was clicked.

Patrick
  • 6,828
  • 3
  • 23
  • 31
  • That's actually not solving the problem - it might be a useful step, but the calculation of the "rendered" (CSS) string length is problematic. – Dennis Guse May 23 '14 at 19:19
  • Did some work on how to follow this approach - first option is to use a monospace font (quite a limitation) or calculate the real font size using Canvas2D (probably not very efficient). – Dennis Guse May 25 '14 at 13:28