我面临以下问题:当我尝试在 a 中选择文本时contenteditable
元素并且选择的结束是元素内容的开始,那么不会触发 select 事件,并且没有Selection
and Range
对象。
有人可以就为什么会发生这种情况或如何防止这种情况给我任何建议吗?
负责获取选择范围的代码:
$('div[contenteditable="true"]').bind("mouseup keyup touchend", function() {
lastCaretIndex = getSelectionRange();
});
function getSelectionRange() {
var sel;
if (window.getSelection) {
sel = window.getSelection();
console.log(sel); // this doesn't print anything event empty string
if (sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection) {
return document.createRange();
}
return null;
}
<div id="main-input" contenteditable="true">Hello world!</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
JSFiddle https://jsfiddle.net/rL9z0bvu/(打开浏览器控制台以确保不会记录该选择)。
问题是您仅在特定事件发生时记录选择更改contenteditable
元素。更具体地说,你有
$('div[contenteditable="true"]').bind("mouseup keyup touchend", // ...
特别是mouseup
当选择更改时,通常会触发事件。除非没有。当您在可编辑区域之外释放鼠标时div
(您在示例中就是这样做的!),然后div
永远不会收到mouseup
事件,因此从不记录选择。
有两种方法可以解决这个问题:
- 监听整个事件
body
。缺点是您会收到更多不影响选择的事件,并且仍然有可能获得mouseup
页面之外的事件。
- 听听selectionchange https://developer.mozilla.org/en-US/docs/Web/Events/selectionchange event.
document.addEventListener('selectionchange', function(event) {
console.log(event.type);
});
<div contenteditable="true">Hello world!</div>
当然,您仍然可以像当前在此事件处理程序中所做的那样访问选择。每次选择更改时都会触发此事件,因此您可能需要throttle https://remysharp.com/2010/07/21/throttling-function-calls it.
下面可以找到其完整实现。
function handler() {
// do whatever you want here
// this shows the selection and all ranges it consists of
var sel = window.getSelection(),
ranges = Array(sel.rangeCount).fill(0).map((_, i) => sel.getRangeAt(i));
ranges = ranges.map((r) => `${r.startOffset}-${r.endOffset}`).join(';');
console.log(`Selection [${ranges}:"${sel.toString()}"]`);
}
function throttle(func) {
var timeoutId = false,
called = false,
wrap = function() {
if (!called) {
clearInterval(timeoutId);
timeoutId = false;
} else {
func();
}
called = false;
};
return function() {
if (timeoutId === false) {
func();
timeoutId = setInterval(wrap, 500);
} else {
called = true;
}
};
}
document.addEventListener('selectionchange', throttle(handler));
<div contenteditable="true">Hello world!</div>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)