med*_*zid 11 javascript range selection contenteditable
这个问题已经被问到,但是直到现在还没有工作的答案,所以我很想再次打开它,希望我们可以找到它.
我有一个contentEditable段落和一个文本输入,当我选择一些文本并单击输入时,选择就消失了.
所以我试图在输入mousedown上保存选择并在mouseup上恢复它,是的它可行(如预期在firefox中)但是...在chrome 中输入失去焦点 :(
看到它在行动(使用铬):https://jsfiddle.net/mody5/noygdhdu/
这是我用过的代码:
HTML
<p contenteditable="true">
Select something up here and click the input below
<br> on firefox the input get the focus and the text still selected.
<br> on chrome the text still selected but the input lose focus
</p>
<input type="text" id="special" style="border: solid blue 1px">
Run Code Online (Sandbox Code Playgroud)
JavaScript的
function saveSelection() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
function restoreSelection(range) {
if (range) {
if (window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.selection && range.select) {
range.select();
}
}
}
var specialDiv = document.getElementById("special");
var savedSel = null;
specialDiv.onmousedown = function() {
savedSel = saveSelection(); // save the selection
};
specialDiv.onmouseup = function() {
restoreSelection(savedSel); // restore the selection
};
Run Code Online (Sandbox Code Playgroud)
小智 7
由于我不能评论maioman(需要一些声誉:)),这里有一点他的aswer:
它在firefox中不起作用的原因是将焦点放在输入字段上会删除选择.
如果你在p上放置一个mouseup事件而不是inputfield上的焦点事件,这一切都可以正常工作:
p.addEventListener('mouseup', () => {
highlight(select()); // save the selection
})
用 a 替换 selection<span>可能是最简单的方法。您还可以使用<iframe>,这是 google 在 Google Docs 中用来在单击 UI 元素时维护文档内文本选择的方法。
使用<span>,解决方案可能是这样的(这个解决方案建立在你的原始代码和这里其他人的想法上,尤其是@Bekim Bacaj)。
!function(doc, win) {
var input = doc.getElementById('special')
, editable = doc.getElementById('editable')
, button = doc.getElementById('button')
, fragment = null
, range = null;
function saveSelection() {
if (win.getSelection) {
sel = win.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (doc.selection && doc.selection.createRange) {
return doc.selection.createRange();
}
return null;
}
/* Not needed, unless you want also restore selection
function restoreSelection() {
if (range) {
if (win.getSelection) {
sel = win.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (doc.selection && range.select) {
range.select();
}
}
}
*/
function saveRangeEvent(event) {
range = saveSelection();
if (range && !range.collapsed) {
fragment = range.cloneContents();
toggleButton();
}
}
function toggleButton() {
button.disabled = !fragment || !input.value.match(/^https?:.*/);
}
toggleButton();
editable.addEventListener('mouseup', saveRangeEvent);
editable.addEventListener('keyup', saveRangeEvent);
button.addEventListener('click', function(event) {
// insert link
var link = doc.createElement('a');
link.href = input.value;
input.value = '';
range.surroundContents(link);
toggleButton();
});
input.addEventListener('keyup', toggleButton);
input.addEventListener('change', toggleButton);
input.addEventListener('mousedown', function(event) {
// create fake selection
if (fragment) {
var span = doc.createElement('span');
span.className = 'selected';
range.surroundContents(span);
}
});
input.addEventListener('blur', function(event) {
// remove fake selection
if (fragment) {
range.deleteContents();
range.insertNode(fragment);
//restoreSelection();
}
fragment = null;
}, true);
}(document, window)
Run Code Online (Sandbox Code Playgroud)
.selected {
background-color: dodgerblue;
color: white;
}Run Code Online (Sandbox Code Playgroud)
<p id="editable" contenteditable="true">
Select something up here and click the input below
<br>on firefox the input get the focus and the text still selected.
<br>on chrome the text still selected but the input lose focus
</p>
<table>
<tr>
<td>
<input type="text" id="special" style="border: solid blue 1px" placeholder="insert valid link incl. http://">
</td>
<td>
<button id="button">Add link</button>
</td>
</tr>
</table>Run Code Online (Sandbox Code Playgroud)
将焦点添加到超时函数中,这应该可以解决您的问题。
setTimeout(function(){
document.getElementById("textToInsert").focus();
}, 1);
Run Code Online (Sandbox Code Playgroud)
jsfiddle: http: //jsfiddle.net/mody5/L5hx9h3k/1/
| 归档时间: |
|
| 查看次数: |
3535 次 |
| 最近记录: |