我想跟踪在CONTENTEDITABLE插入符/光标的移动。 我不知道什么是做到这一点的最好办法,但。
目前,我正在听的点击,KEYDOWN,KEYUP。 (当然,按键也不会闪光的东西像箭头键或Ctrl-X)。
虽然点击做工精细,用的keydown问题是尖的实际运动之前,它的发射,所以当我查询当前文档选择范围,给我的老位置,而不是新的。 但是,如果我靠KEYUP来获得更新的位置,它触发为时已晚:插入符号只要按下该键上下移动,但关键是后来被释放的任意时间。
因为事情像CKEDITOR是能够做到这一点这必须是可能的。 任何提示?
这是很好的阅读,人们都在谈论CKEditor的:)。 我是它的开发商之一,我没有被选上的工作很多,但我会尽力帮助。
我所知道的是,我们已经有了一个内部selectionChange
事件。 所以,当我们检查它是否改变了? ......每每200ms至少一次:)请参见:
http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/selection/plugin.js#L39
我们还检查选择每次我们知道,它可能已经改变(例如,通过API或KEYUP /鼠标松开或对本地selectionchange时间- http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/selection /plugin.js#L554 )。 所以......几乎所有的时间:)据我所知,我们做了一些技巧,因此它不烧你的CPU,但它仍然是沉重的。 但是,如果我们这样做,那么它的唯一可能的途径有这样的工作这么好。
不幸的是,选择的处理是目前wysiwygs世界上最坏的任务。 它是如此打破了一切 - 新老浏览器。 我在上面链接的文件中超过75%的LOC是黑客和技巧。 这是完全疯狂。
在Mozilla和Opera,处理键和鼠标事件讨厌的业务是唯一的选择。 它不仅是繁琐的,它也不会覆盖每一个案例:有可能改变通过编辑和上下文菜单的选择(通过全选,例如)。 为了弥补这一点,你想也需要添加某种选择对象的投票。
然而,在IE(回至少5.5一路)和最近十岁上下的WebKit,有selectionchange
事件上的文件时将触发的选择变化。
document.onselectionchange = function() {
alert("Selection changed!");
};
有一个机会,Mozilla不会支持它的未来: https://bugzilla.mozilla.org/show_bug.cgi?id=571294
这是不是你说的原因一件容易的事。 我想出了这样的一些杂牌组装电脑:
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
事件,这实际上是在胡说八道另一个痛苦。
最后,我决定这是不值得,我的目的的努力。 也许你有不同的需求。
WRT catching the event after the selection is updated: I simply wrap my handler functions in timeouts:
editor.onkeydown = function() {
window.setTimeout( function(){
// Your handler code here
}, 0 );
};
This registers your handler to be executed in the browser's event loop as soon as possible, but after the current (eg click) event is processed. But be aware of possible races if you have other scripts modifying the content; there is no guarantee that your timeout is the next in line to be run.