document.execCommand 在折叠范围的 IE 中无法正常工作(用户选择)
document.execCommand not working properly in IE with collapsed range (user selection)
我面临以下问题:
When I put cursor to some position and then apply execCommand('bold') in all browsers except IE next typed text will be bold, but in IE it makes all word bold.
为了更清楚,这里有图片。
Normal/expectable 行为(Crhome、Firefox 等):
IE 中的行为:
下面是代码片段,也可以在 jsfiddle.
上找到
var lastCaretIndex = null;
document.addEventListener('selectionchange', function(event) {
var taget = event.target;
if (taget.activeElement.id == 'main-input') {
lastCaretIndex = getSelectionRange();
console.log(typeof lastCaretIndex);
console.log(lastCaretIndex);
}
});
function afterFocus() {
var s = null;
if (window.getSelection) {
s = window.getSelection();
} else {
s = document.getSelection();
}
if (lastCaretIndex == null) {
lastCaretIndex = document.createRange();
} else if (s.rangeCount > 0) {
s.removeAllRanges();
s.addRange(lastCaretIndex);
}
}
function getSelectionRange() {
var sel;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection) {
return document.createRange();
}
return null;
}
$(document).on('click', '.icon-bold', function () {
document.getElementById('main-input').focus();
afterFocus();
document.execCommand('bold');
handleButtonActiveState($(this));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="main-input" contenteditable="true">Hello world!</div>
<button type="button" class="icon-bold">Bold</button>
有人可以帮助我吗?我试图在互联网上寻找解决方案,但没有得到任何结果。好像和TextRange没有关系。
P.S。如果还需要其他东西,请告诉我。
您可以使用 Andibioticum's workaround 在 Internet Explorer 中获得与在 Chrome 和 Firefox 中相同的行为。他在空的选定范围内插入一个虚拟字符,执行操作,然后删除虚拟字符。
我根据您的情况进行了调整,使用 IE browser detection technique suggested by Royi, combined with checking for document.all
for older IE versions. You can see the result in this jsFiddle 和下面的代码片段。
var range = null;
document.addEventListener('selectionchange', function(event) {
var taget = event.target;
if (taget.activeElement.id == 'main-input') {
range = getSelectionRange();
}
});
function isIE() {
return document.all || (!!window.MSInputMethodContext && !!document.documentMode);
}
function execBoldCommand() {
if (document.getSelection() != "") {
document.execCommand('bold');
} else {
var s = null;
if (window.getSelection) {
s = window.getSelection();
} else {
s = document.getSelection();
}
if (isIE()) {
var selRange = s.getRangeAt(0);
//Insert node with dummy text 'd'
var newNode = document.createTextNode('d');
selRange.insertNode(newNode);
s.removeAllRanges();
s.addRange(selRange);
//Execute command on dummy
document.execCommand('bold');
//Delete dummy from range
selRange.setStart(newNode, 0);
selRange.setEnd(newNode, 1);
selRange.deleteContents();
s.removeAllRanges();
s.addRange(selRange);
} else {
if (range == null) {
range = document.createRange();
}
s.removeAllRanges();
s.addRange(range);
document.execCommand('bold');
}
}
}
function getSelectionRange() {
var sel;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection) {
return document.createRange();
}
return null;
}
$(document).on('click', '.icon-bold', function() {
$('#main-input').focus();
execBoldCommand();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="main-input" contenteditable="true">Hello world!</div>
<button type="button" class="icon-bold">Bold</button>
我面临以下问题:
When I put cursor to some position and then apply execCommand('bold') in all browsers except IE next typed text will be bold, but in IE it makes all word bold.
为了更清楚,这里有图片。
Normal/expectable 行为(Crhome、Firefox 等):
IE 中的行为:
下面是代码片段,也可以在 jsfiddle.
上找到var lastCaretIndex = null;
document.addEventListener('selectionchange', function(event) {
var taget = event.target;
if (taget.activeElement.id == 'main-input') {
lastCaretIndex = getSelectionRange();
console.log(typeof lastCaretIndex);
console.log(lastCaretIndex);
}
});
function afterFocus() {
var s = null;
if (window.getSelection) {
s = window.getSelection();
} else {
s = document.getSelection();
}
if (lastCaretIndex == null) {
lastCaretIndex = document.createRange();
} else if (s.rangeCount > 0) {
s.removeAllRanges();
s.addRange(lastCaretIndex);
}
}
function getSelectionRange() {
var sel;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection) {
return document.createRange();
}
return null;
}
$(document).on('click', '.icon-bold', function () {
document.getElementById('main-input').focus();
afterFocus();
document.execCommand('bold');
handleButtonActiveState($(this));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="main-input" contenteditable="true">Hello world!</div>
<button type="button" class="icon-bold">Bold</button>
有人可以帮助我吗?我试图在互联网上寻找解决方案,但没有得到任何结果。好像和TextRange没有关系。
P.S。如果还需要其他东西,请告诉我。
您可以使用 Andibioticum's workaround 在 Internet Explorer 中获得与在 Chrome 和 Firefox 中相同的行为。他在空的选定范围内插入一个虚拟字符,执行操作,然后删除虚拟字符。
我根据您的情况进行了调整,使用 IE browser detection technique suggested by Royi, combined with checking for document.all
for older IE versions. You can see the result in this jsFiddle 和下面的代码片段。
var range = null;
document.addEventListener('selectionchange', function(event) {
var taget = event.target;
if (taget.activeElement.id == 'main-input') {
range = getSelectionRange();
}
});
function isIE() {
return document.all || (!!window.MSInputMethodContext && !!document.documentMode);
}
function execBoldCommand() {
if (document.getSelection() != "") {
document.execCommand('bold');
} else {
var s = null;
if (window.getSelection) {
s = window.getSelection();
} else {
s = document.getSelection();
}
if (isIE()) {
var selRange = s.getRangeAt(0);
//Insert node with dummy text 'd'
var newNode = document.createTextNode('d');
selRange.insertNode(newNode);
s.removeAllRanges();
s.addRange(selRange);
//Execute command on dummy
document.execCommand('bold');
//Delete dummy from range
selRange.setStart(newNode, 0);
selRange.setEnd(newNode, 1);
selRange.deleteContents();
s.removeAllRanges();
s.addRange(selRange);
} else {
if (range == null) {
range = document.createRange();
}
s.removeAllRanges();
s.addRange(range);
document.execCommand('bold');
}
}
}
function getSelectionRange() {
var sel;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection) {
return document.createRange();
}
return null;
}
$(document).on('click', '.icon-bold', function() {
$('#main-input').focus();
execBoldCommand();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="main-input" contenteditable="true">Hello world!</div>
<button type="button" class="icon-bold">Bold</button>