1

I am faced with following issue:

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.

Here is images to make it more clearly. Normal/expectable behavior (Crhome, Firefox etc.): enter image description here

Behavior in IE:

enter image description here

Below is codesnippet and it also could be found on 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>

Can somebody please help me. I tried to find solution in Internet but didn't get any results. It seems like it doesn't related with TextRange.

P.S. please let me know if something else is needed.

nowiko
  • 2,507
  • 6
  • 38
  • 82

1 Answers1

1

You can use Andibioticum's workaround to get the same behavior in Internet Explorer as in Chrome and Firefox. He inserts a dummy character in the empty selected range, performs the action, and then removes the dummy character.

I adapted it to your case, using the 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 and in the code snippet below.

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>
Community
  • 1
  • 1
ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
  • Thank you. I have rechecked this in IE and it works!) I will assign bounty to you as soon as it will be available. but I still cant get the reason why it behaves in such a way in IE. Magic... – nowiko Apr 08 '17 at 08:22