[英]JavaScript 'contenteditable' — Getting/Setting Caret Position
我已经阅读了几篇关于插入符号的帖子,但似乎都没有回答我的特定问题。
问题 :我希望插入符号作为div1出现在div2上的确切位置
所以,我需要一些方法来读取用户点击div1的位置,然后当div2出现时将光标/插入符号放在同一位置,这样就是一组getCaretLocation(in_div_id)和setCaretLocation(in_div_id)函数。
有办法吗?
谢谢 -
简答 :你做不到
答案很长 :你将面临的问题是你将能够获得div1上click事件的(x,y)坐标,但是任何实现的插入位置都要求你知道插入符号在内容中的位置(这是插入符号前面的字符数)。
要将(x,y)坐标转换为字符位置,您实际上需要知道之前有多少个字符(即,如果文本是ltr,则保留在当前行和上面的字符处)。
如果使用固定宽度字体,则可以简化问题:将(x,y)坐标映射到字符网格上的(线,列)坐标。
但是,您仍然面临不知道文本如何被包装的问题。 例如 :
------------------
|Lorem ipsum |
|dolor sit amet |
|consectetur |
|adipiscing elit |
------------------
如果用户点击了dol中的d ,你知道该字符是第二行的第一个,但是在不知道包装算法的情况下,你无法知道它是“Lorem ipsum dolor sit中的第13个字符...... ”。 并且无法保证这种包装算法在浏览器和平台之间是相同的。
现在,我想知道为什么你会首先使用2个不同的同步div
? 当用户点击(或悬停)时,仅使用一个div并将其内容设置为可编辑是不是更容易?
你可以,基本上你需要在你的第一个div上设置可编辑的临时内容以捕获插入符号位置
$('div1').hover(function()
{ $(this).attr('contenteditable','true');
},function()
{ $(this).removeAttr('contenteditable');
}).mouseup(function()
{ var t = $(this);
// get caret position and remove content editable
var caret = t.getCaret();
t.removeAttr('contenteditable');
// do your div switch stuff
...
// and apply saved caret position
$('div2').setCaret(caret);
});
现在只需要获取/设置插入符号方法:)
编辑>这是我自己的,( 现场演示 )
getSelection:function($e)
{ if(undefined === window.getSelection) return false;
var range = window.getSelection().getRangeAt(0);
function getTreeOffset($root,$node)
{ if($node.parents($root).length === 0) return false; // is node child of root ?
var tree = [], treesize = 0;
while(1)
{ if($node.is($root)) break;
var index, $parent = $node.parent();
index = $parent.contents().index($node);
if(index !== -1) { tree[treesize++] = index; } $node = $parent;
}; return tree.reverse();
}
var start = getTreeOffset($e,$(range.startContainer));
var end = getTreeOffset($e,$(range.endContainer));
if(start & end === false) return false;
return {start:start,end:end,startOffset:range.startOffset,endOffset:range.endOffset};
}, setSelection:function($e,s,win)
{ $e.focus(); if(s === false) return; var sel = win.getSelection(); sel.removeAllRanges();
function getNode($e,s)
{ var node = $e;
for( var n=0;n<s.length;n++ )
{ var index = s[n]; if(index < 0) break;
node = node.contents(':eq('+index+')');
} return node.get(0);
}
var start = getNode($e,s.start), end = getNode($e,s.end), range = win.document.createRange();
range.setStart(start,s.startOffset); range.setEnd(end,s.endOffset); sel.addRange(range);
}
您可以在插入符号处插入一个小的span-element,获取其位置并将其删除。 对于跨浏览器范围和选择库,请参阅rangy 。
单击元素时,将创建一个长度为零的Selection对象(从element.getSelection()获取,其中element是有问题的div)。 该对象的focusOffset将告诉您单击该div中的第74个字符(这是Adrien所说的在不同答案中不可能的事情)。
读取文本中的插入位置,然后在编辑窗口中设置插入位置。
听起来你正在尝试进行内联编辑...你看过jeditable插件了吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.