Вот готовое решение:
class SelectionSaver
isMs = /edge|msie|trident/i.test(navigator.userAgent)
isInteractive = off
if isMs
addEventListener 'mousedown', =>
isInteractive = on
, on
addEventListener 'mouseup', =>
isInteractive = off
, on
constructor: ->
@selection = getSelection()
@anchorNode = null
@anchorOffset = null
@focusNode = null
@focusOffset = null
return
clear: ->
@anchorNode = null
@anchorOffset = null
@focusNode = null
@focusOffset = null
return
save: ->
@anchorNode = @selection.anchorNode
@anchorOffset = @selection.anchorOffset
@focusNode = @selection.focusNode
@focusOffset = @selection.focusOffset
return
restore: ->
if isMs and isInteractive then return
@selection.removeAllRanges()
unless @anchorNode then return
range = document.createRange()
range.setStart(@anchorNode, Math.min(@anchorOffset, @anchorNode.length))
@selection.addRange(range)
@selection.extend(@focusNode, Math.min(@focusOffset, @focusNode.length))
return