After double click, selection range can be obtained correctly on onclick event but when I again click on the selected text then updated selection range should be returned by window selection but this is not happening. Can anybody tell me if this is a bug in javascript selection or they have made it this way. And what could be the solution to get the updated range apart from timer.
<div id="xyz" contenteditable="true">Hello world</div>
<span class="status">Selected text : </span>
javascript code :
function yourFunction() {
if (window.getSelection) {
var selectionRange = window.getSelection();
$('.status').text(selectionRange.toString());
}
}
$('#xyz').click(function () {
$('.status').text('Mouse click');
yourFunction();
})
Example here
You fiddle is working just fine. But, yes sometimes when you do selections in quick succession, then it fails to register the click.
The problem really lies in the way you have implemented it on click
on the text input
itself. A click event is generated when a mouseup follows a mousedown. A selection happens when you mousedown then drag and then mouseup.
If you separate out the selection retrieval then this problem won't occur.
See this updated fiddle: http://jsfiddle.net/zRr4s/21/
Here, the selection retrieval is donw on a button click, instead of the input itself.
i.e., instead of:
$('#xyz').click(function (e) { ...
using this:
$('#btn').click(function () { ...
where, btn is:
<input id="btn" type="button" value="get selection" />
Hope that helps.
Update:
If you insist on handling event only on the input, then listening mouseup would be better option:
See this fiddle: http://jsfiddle.net/zRr4s/22/
$('#xyz').on("mouseup", function (e) { ...
Update 2:
To handle your requirement of in-context click, you will have to first clear the selection. For this to happen you will have to handle mousedown. So, that will defeat your purpose of having only one handler. Anyway,
You updated fiddle: http://jsfiddle.net/zRr4s/29/
And, this is how you do it:
$('#xyz').on("mousedown", function () {
clearTheSelection();
});
Where clearTheSelection
is another function:
function clearTheSelection() {
if (window.getSelection) {
if (window.getSelection().empty) { // Chrome
window.getSelection().empty();
} else if (window.getSelection().removeAllRanges) { // Firefox
window.getSelection().removeAllRanges();
}
} else if (document.selection) { // IE?
document.selection.empty();
}
}
The complete code for the above function taken from this answer: https://stackoverflow.com/a/3169849/1355315
Hope that completes all your problems.
The fiddle provided in the question works fine in Edge and IE11 but doesn't work in Chrome. I found a trick to make it work everywhere. Add the following event handler in addition to the click
handler you already have:
$(document).on("selectionchange", function () {
yourFunction();
});
Some notes:
selectionchange
is a document level event, you cannot bind it to specific element (but you can find out whether you need to handle it within the event handler)
Handling selectionchange
without also handling click
doesn't work well in Edge and IE11
According to MDN, browser support is good enough: https://developer.mozilla.org/en-US/docs/Web/API/Document/selectionchange_event
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With