Selecting range on focus quickly gets deselected in Safari - javascript

I have some javascript which works fine in Chrome/Firefox so that when a user focus's on a contentEditable div, the entire contents get highlighted. In Safari, however, I can see it get highlighted, then quickly the selection get's overridden to where the user clicks.
The following runs in onFocus:
const selection = window.getSelection(); // Shouldn't be undefined, but I guess could be?
if (selection) {
const range = document.createRange();
range.selectNodeContents(event.target);
selection.removeAllRanges();
selection.addRange(range);
}

Related

Using javascript to select text and the containing element using createRange

I'm rolling my own generic wysiwyg editor but Im stuck selecting some text. I'm using a div with contenteditable set to true to enter the text into. The problem is I'm using a <var> tag to highlight some text that the user is supposed to delete and rewrite in their own words. When the text inside the <var> tag is clicked it highlights it as I expect but when you hit backspace it only deletes the text and not the tags (<var>). How can I tell the selection to grab a few more characters on each end of the selection so it also deletes the <var> tags? I'm using the following to make the selection happen.
var range = document.createRange();
range.selectNodeContents(elem);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
Placed function on the div's click event.
Selected the <var> tag.
Used .selectNode rather than .selectNodeContents.
Browsers handle it differently though. Some will add <i></i> tags when you enter more text, others don't, but this does remove the <var> tag completely....
var myDiv = document.getElementById("myDiv");
var elem = document.getElementById("myVar");
myDiv.addEventListener("click", function() {
var range = document.createRange();
range.selectNode(elem);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
});
<div contenteditable="true" id="myDiv">
Hello, this<var id="myVar"> is a test</var> of the editor
</div>

Set window selection from a previously saved selection object

If I have a selection object from a textarea (with a class of my-text-area) using window.getSelection(), if this selection loses focus (say if the user clicks on another input field), is there a way I can set this selection again programmatically?
I've tried doing something like this:
When I have focus:
var currentSelection = window.getSelection();
After I lose focus and want to set the selection again:
var range = currentSelection.getRangeAt(0);
range.selectNode($('.my-text-area')[0]);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
This seems to select everything in my textarea though, not just the small selected area initially.
Just found the excellent Rangy library, that contains a Selection Save and Restore module that does exactly this: https://github.com/timdown/rangy/wiki/Selection-Save-Restore-Module

How to set the cursor in the child of a contentEditable element?

I want to know how to set the cursor in the child of an editable element. I have a content editable DIV with a SPAN inside and I want to set the cursor in the SPAN when the DIV is clicked to prevent someone typing in the DIV.
<div class="custom-input" spellcheck="true" contenteditable="true">
"NOT HERE"
<span data-type="text">
"TYPE HERE"
<br>
</span>
</div>
I have tried to do this with .focus() in jQuery, and it works but it just highlights the SPAN and the cursor remains in the DIV.
I'm trying to make something like Facebook chat does. Facebook chat uses contenteditable elements for the chat input, and if you click anywhere in the chat box the cursor always is focused in a SPAN label that is used for the input.
I had to do this recently and the below is what I ended up with.
NOTE: This will not appear to work here or on jsFiddle due the sandboxing and whatnot. Run the code on your localhost or hosted server and you'll see it works.
$(document).ready(function() {
var $element = $('.type-here');
createCaretPlacer($element, false); // set cursor and select text
createCaretPlacer($element, true, true); // set cursor at start
createCaretPlacer($element, true, false); // set cursor at end
});
function createCaretPlacer($element, collapse, atStart) {
var el = $element[0]; // get the dom node of the given element
el.focus(); // focus to the element
// feature test to see which methods to use for given browser
if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
// handle real browsers (not IE)
var range = document.createRange(); // create a new range object
range.selectNodeContents(el); // add the contents of the given element to the range
if(collapse) range.collapse(atStart); // collapse the rage to either the first or last index based on "atStart" param
var sel = window.getSelection(); // Returns a Selection object representing the range of text selected by the user or the current position of the caret.
sel.removeAllRanges(); // removes all ranges from the selection, leaving the anchorNode and focusNode properties equal to null and leaving nothing selected.
sel.addRange(range); // add the range we created to the selection effectively setting the cursor position
}
else if (typeof document.body.createTextRange != "undefined") {
// handle IE
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
if(collapse) textRange.collapse(atStart);
textRange.select();
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="custom-input" spellcheck="true" contenteditable="true">
"NOT HERE"
<span data-type="text" class="type-here">
"TYPE HERE"
<br>
</span>
</div>

using jquery to operate sth on selected input parts

My goal is to change the font-format of the selected part of the input text using jQuery.
plz show me the way that works in firefox(if there isn't a way for it doesn't matter...). my problem is getting the selected part (ranges) and working with that ranges but i am not sure if its this way.plz show me the way.
var userSelection;
if (window.getSelection) {
userSelection = window.getSelection();
} else if (document.selection) { // Opera
userSelection = document.selection.createRange();
}
i am designing a full text editor using html.

Range Object Mozilla Firefox startOffset not working correctly

I am building an Editor with the Range Object from Mozilla and Internet Explorer...
The thing is the following:
I have an Text in an div Box and now I select this text and get the start and offset with the Range Object -> with startOffset and endOffset.
In IE it works fine but in the Firefox I have the Problem, that repeated Text is not working correctly - it always takes only the first Text and is ignoring the other text range ...
So here my code:
function get_start() {
var markiert = window.getSelection().getRangeAt(0);
alert(markiert.startOffset);
}
function get_ende() {
var markiert = window.getSelection().getRangeAt(0);
alert(markiert.endOffset);
}
And it will display the start- and end-point of the selected string.

Categories