Javascript 确定单击时HTML元素中字符的位置索引

Javascript 确定单击时HTML元素中字符的位置索引,javascript,position,character,Javascript,Position,Character,我有一个HTML元素,里面只有可见的文本。此示例是一个元素,但它可以是、或其他DOM元素 这是一个简单的例子。 单击时,我可以获得光标在div表面上的位置,但我需要在单击时确定最近字符的位置和/或其在div.innerHTML字符串中的索引 我在SVG文本实体中的“getCharNumAtPosition”方法中发现了类似的实现 有可能在JavaScript中实现这样一个与HTML一起工作的函数吗 (如果这些解决方案可以在大多数现代浏览器中移植,可以与大多数书面语言一起使用,并且基于相对稳定的

我有一个HTML元素,里面只有可见的文本。此示例是一个
元素,但它可以是
或其他DOM元素

这是一个简单的例子。
单击时,我可以获得光标在div表面上的位置,但我需要在单击时确定最近字符的位置和/或其在div.innerHTML字符串中的索引

我在SVG文本实体中的“getCharNumAtPosition”方法中发现了类似的实现

有可能在JavaScript中实现这样一个与HTML一起工作的函数吗


(如果这些解决方案可以在大多数现代浏览器中移植,可以与大多数书面语言一起使用,并且基于相对稳定的标准,这样以后就不会出现问题,那么它们将是最有用的。)

您可以使用JavaScript将每个字符分解为自己的SPAN标记,并为每个字符添加onclick事件。然后,单击范围时,从事件数据中读取x、y位置

此外,您还可以访问使用event.target.innerHTML单击的角色

$('div').click( function () {
  getSelectionPosition (); 
});


function getSelectionPosition () {
  var selection = window.getSelection();
  console.log(selection.focusNode.data[selection.focusOffset]);
  alert(selection.focusOffset);
}
这适用于大多数浏览器的“点击”和“范围”。(
selection.type=“caret”
/
selection.type=“range”

selection.focusOffset()
提供内部节点中的位置。例如,如果元素嵌套在
标记中,它将或多或少地为您提供内部元素中的位置,而不是全文。我无法“选择”具有
focusOffset
和“插入符号”类型的子标记的第一个字母(单击,而不是范围选择)。当您单击第一个字母时,它给出了标记加1开头之前最后一个元素的位置。当你点击第二个字母时,它正确地给出了“1”。但是我没有找到访问子元素的第一个元素(偏移量0)的方法。这种“选择/范围”的东西似乎有问题(或者对我来说非常不直观)^^

但是它使用起来非常简单,没有嵌套元素!(适用于您的

重要编辑2015-01-18: 这个答案在被接受时仍然有效,但由于下面给出的原因不再有效。其他答案现在最有用。

  • 马修的一般回答
  • Douglas Daseco提供的工作示例
Firefox和Chrome都调试了
window.getSelection()
行为。不幸的是,它现在对于这个用例是无用的。(阅读文件,如第9条及以上,其行为应相同)

现在,字符的中间用于确定偏移量。这意味着点击一个角色可以返回两个结果。0或1表示第一个字符,1或2表示第二个字符,以此类推

我更新了


请注意,如果调整窗口大小(Ctrl+鼠标),Chrome上的某些单击行为会出现问题。

此示例适用于中等大小的文本块的快速加载,可移植且健壮。虽然它的优雅不是很明显,但可靠性在于在国际角色和DOM事件侦听器1之间创建简单的一对一对应关系

最好只依赖广泛采用的字符编码、DOM和ECMA标准,如本例所示。其他方法通常依赖于低级事件目标属性或函数,如getSelection(),这些属性或函数随着时间的推移既不稳定,也不能跨浏览器和语言移植

对于特定的应用程序,可以通过多种方式修改示例代码。例如,可以使用其他机制来选择为charClick回调初始化哪些DOM对象。在i循环中也可以支持代理项对

  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="utf-8">
      <title>Character Click Demo</title>
      <script type='text/javascript'>
          var pre = "<div onclick='charClick(this, ";
          var inf = ")'>";
          var suf = "</div>"; 
          function charClick(el, i) {
              var p = el.parentNode.id;
              var s = "para '" + p + "' idx " + i + " click";
              ele = document.getElementById('result');
              ele.innerHTML = s; }
          function initCharClick(ids) {
              var el; var from; var length; var to; var cc;
              var idArray = ids.split(" ");
              var idQty = idArray.length;
              for (var j = 0; j < idQty; ++ j) {
                  el = document.getElementById(idArray[j]);
                  from = unescape(el.innerHTML);
                  length = from.length;
                  to = "";
                  for (var i = 0; i < length; ++ i) {
                      to = to + pre + i + inf + from.charAt(i) + suf;
                  el.innerHTML = to; } }
      </script>
      <style>
          .characters div {
              padding: 0;
              margin: 0;
              display: inline }
      </style>
  </head>
  <body class='characters' onload='initCharClick("h1 p0 p2")'>
      <h1 id='h1'>Character Click Demo</h1>
      <p id='p0'>Test &#xE6;&#x20AC; &ndash; &#xFD7;&#xD8; &mdash; string.</p>
      <p id='p1'>Next In many cases, a possible solution can be to add zero-width space character (U+200B) between each char of the content of the  tag. Then using javascript 
window.getSelection().focusOffset
+ some simple computations does the job.

Sample html code (including zero-width space characters):

<div onclick='magic(this)'>T​h​i​s​ ​i​s​ ​a​ ​s​i​m​p​l​e​ ​e​x​a​m​p​l​e​.</div>

字符点击演示
var pre=“”;
var suf=“”;
函数charClick(el,i){
var p=el.parentNode.id;
var s=“para'”+p+“'idx”+i+“点击”;
ele=document.getElementById('result');
ele.innerHTML=s;}
函数initCharClick(ids){
var el;var from;var长度;var to;var cc;
var idArray=ids.split(“”);
变量idQty=idArray.length;
对于(变量j=0;j测试æ;€;&ndash;࿗;Ø;&mdash;字符串


接下来在许多情况下,一个可能的解决方案是在标记内容的每个字符之间添加零宽度空格字符(U+200B)。然后使用javascript

window.getSelection().focusOffset
+一些简单的计算完成这项工作

示例html代码(包括零宽度空格字符):

T​H​我​s​ ​我​s​ ​A.​ ​s​我​M​P​L​E​ ​E​x​A.​M​P​L​E​.
javascript代码示例:


函数魔术(e)
{
var s,p,c;
s=e.innerHTML;
p=window.getSelection().focusOffset;
c=s.charAt((p>>1)>1)+“char:”+c);
}
似乎工作广泛,甚至在internet explorer上


jsFidle:

我在考虑这个想法,但我想在一个使用HTML元素的简单记事本web应用程序中实现这个功能,如果我对每个字符使用跨距,它将占用大量内存,我想找到一个低级别的解决方案,如果它存在的话:)我想说你可以计算
<script>
    function magic(e)
    {
        var s, p, c;
        s = e.innerHTML;
        p = window.getSelection().focusOffset;
        c = s.charAt((p >> 1) << 1);
        alert("index:" + (p >> 1) + " char: " + c);
    }
</script>