我想跟踪插入符号/光标的移动。不过,我不确定最好的方法是什么。
我正在听click,keydown,keyup。 (按键当然甚至不会触发箭头键或ctrl-x之类的东西。)
虽然点击工作正常,但keydown的问题是它在插入符号实际移动之前被触发,所以当我查询当前文档选择范围时,我得到旧位置而不是新位置。但是,如果我依靠keyup获取更新的位置,它会触发太晚:按下键时插入符号会移动,但键会在任意时间后释放。
这一定是可能的,因为CKeditor之类的东西能够做到这一点。任何提示?
答案 0 :(得分:10)
很高兴看到人们在谈论CKEditor :)。我是其开发人员之一,我没有在选择方面做太多工作,但我会尽力帮助。
我所知道的是,我们有一个内部selectionChange
事件。那么我们什么时候检查它是否改变了? ......每200ms至少一次:)见:
http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/selection/plugin.js#L39
每当我们知道它可以被更改时(例如,通过API或keyup / mouseup或本地选择更改 - http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/selection/plugin.js#L554),我们也会检查选择。所以...几乎所有的时间:) AFAIK我们做一些技巧,所以它不会烧掉你的CPU,但它仍然很重。但是,如果我们这样做了,那么这是唯一可行的方法,让它工作得非常好。
不幸的是,选择处理是目前wysiwygs世界中最差的任务。它在所有新旧浏览器中都如此破碎。我上面链接的文件中超过75%的LOC是黑客和技巧。这完全是疯狂的。
答案 1 :(得分:5)
在Mozilla和Opera中,处理键和鼠标事件的讨厌业务是您唯一的选择。它不仅非常繁琐,而且并不涵盖所有情况:可以通过编辑和上下文菜单(例如,通过全选)更改选择。为了解决这个问题,您还需要添加某种选择对象的轮询。
然而,在IE中(一直回到至少5.5)和最近的WebKit,只要选择发生变化,就会在文档上触发selectionchange
event。
document.onselectionchange = function() {
alert("Selection changed!");
};
Mozilla将来有可能支持它:https://bugzilla.mozilla.org/show_bug.cgi?id=571294
答案 2 :(得分:0)
由于你说的原因,这不是一件容易的事。我想出了一些像这样的kludge:
var caretInterval, caretOffset;
document.addEventListener("keydown", function(e) {
if (!e.target.contentEditable || caretInterval) return;
if (e.keyCode !== 37 && e.keyCode !== 39) // Left and right
return;
var sel = getSelection();
caretInterval = setInterval(function() {
if (sel.type === "Caret") caretOffset = sel.baseOffset;
}, 50);
});
document.addEventListener("keyup", function(e) {
if (e.keyCode !== 37 && e.keyCode !== 39) // Left and right
return;
clearInterval(caretInterval);
caretInverval = null;
var sel = getSelection();
if (sel.type === "Caret") caretOffset = sel.baseOffset;
});
如果有人试图同时向左和向右按,可能会出现一个小问题。对于ctrl-X和ctrl-V,您应该捕获cut
和paste
事件,这实际上是另一个痛苦的事情。
最后,我认为为我的目的付出的努力是不值得的。也许你有不同的需求。
答案 3 :(得分:0)
在选项更新后,WRT捕获事件:我只是将我的处理函数包装在超时中:
editor.onkeydown = function() {
window.setTimeout( function(){
// Your handler code here
}, 0 );
};
这将注册您的处理程序,以便尽快在浏览器的事件循环中执行,但在处理当前(例如,单击)事件之后。但是如果你有其他脚本修改内容,请注意可能的比赛;无法保证您的超时是下一个要运行的行。