Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
180 views
in Technique[技术] by (71.8m points)

javascript - Determine the position index of a character within an HTML element when clicked

I have an HTML element with only visible text inside. This example is a <div> element, but it could be a <span>, <p>, or other DOM element.

<div>This is a simple example.</div>

When clicked, I can get the position of the cursor on the surface of the div, but I need to determine the position of the nearest character and/or its index into the div.innerHTML string at the time of the click.

I found a similar implementation in the "getCharNumAtPosition" method in SVG text entities here.

Is it possible to implement such a function in JavaScript that works with HTML?

(Solutions would be most useful if they are portable across most modern browsers, work with most written languages, and are based on relatively stable standards so that they will not become buggy later.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
$('div').click( function () {
  getSelectionPosition (); 
});


function getSelectionPosition () {
  var selection = window.getSelection();
  console.log(selection.focusNode.data[selection.focusOffset]);
  alert(selection.focusOffset);
}

This works with "click", as well as with a "range" for most browsers. (selection.type = "caret" / selection.type = "range").

selection.focusOffset() gives you the position in the inner node. If elements are nested, within <b> or <span> tags for example, it will give you the position inside the inner element, not the full text, more or less. I'm unable to "select" the first letter of a sub tag with focusOffset and "caret" type (click, not range select). When you click on the first letter, it gives the position of the last element before the start of tag plus 1. When you click on the second letter, it correctly gives you "1". But I didn't find a way to access the first element (offset 0) of the sub element. This "selection/range" stuff seems buggy (or very non-intuitive to me). ^^

But it's quite simple to use without nested elements! (Works fine with your <div>)

Here is a fiddle

Important edit 2015-01-18:

This answer worked back when it was accepted, but not anymore, for reasons given below. Other answers are now most useful.

  • Matthew's general answer
  • The working example provided by Douglas Daseeco.

Both Firefox and Chrome debugged window.getSelection() behavior. Sadly, it is now useless for this use case. (Reading documentation, IE 9 and beyond shall behave the same).

Now, the middle of a character is used to decide the offset. That means that clicking on a character can give back 2 results. 0 or 1 for the first character, 1 or 2 for second, etc.

I updated the JSFiddle example.

Please note that if you resize the window (Ctrl + mouse), the behavior is quite buggy on Chrome for some clicks.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...