In our project we have a content editable div and another div that works as a button that displays some options. The user chooses one of those options and the value is inserted at the caret of the content editable div. So I am trying to get the selected range value from the content editable div to insert the value text at the caret.
I implemented it using the blur() event on the content editable div to get the selection before losing the focus, saving that range data and using it on the div click event. In Chrome/Edge works fine, but in Firefox/Safari it does not.
What I do not understand is that when using an input button, it works in all browsers, but when using a div as a button, it does not work in Firefox/Safari.
JSFiddle: https://jsfiddle.net/v7secq04/4/
The code:
HTML
<!-- input button and div used as button -->
<input type="button" id="selection-button" value="Get selection">
<div id="selection-div" style="border-style: solid; width: 100px;cursor: pointer;">Selection DIV</div>
<!-- editable div -->
<div id="editor" contenteditable="true" style="border-style: solid; height: 150px;">Please select some text.</div>
<!-- inputs to display the range values -->
Range start: <input id="start" type="text"/><br/>
Range end: <input id="end" type="text"/>
JS
var start = 0,
end = 0;
// On clicking on the button or the div, the editor div blur event is triggered.
// We get the range start and end, and store them.
$( "#editor" ).blur(function() {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(editor);
preSelectionRange.setEnd(range.startContainer, range.startOffset);
start = preSelectionRange.toString().length;
end = start + range.toString().length;
});
// After the blur event is finished, the click event is triggered.
// Start and end values are displayed in the inputs
$('#selection-button, #selection-div').on('click', function() {
$('#start').val(start);
$('#end').val(end);
start = 0;
end = 0;
});
To reproduce it:
Does someone know why? Is there any way to get the correct range data using a div button?
Thanks!
I got it working by splitting your event listeners on the button and the div in a click and mousedown.
<script type="text/javascript">
var start = 0,
end = 0;
$(() => {
$('#selection-div').on('mousedown', getSelection);
$('#selection-button').on('click', getSelection);
function getSelection() {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(document.getElementById('editor'));
preSelectionRange.setEnd(range.startContainer, range.startOffset);
start = preSelectionRange.toString().length;
end = start + range.toString().length;
$('#start').val(start);
$('#end').val(end);
// Not needed, as you would override it on every click
//start = 0;
//end = 0;
}
})
</script>