I am trying to delete a node from a contentEditable div, but nothing happens on range.deleteContents():
var parseLine = function(){
var el = document.getElementById('Editor');
var selection = window.getSelection();
let text = $(selection.anchorNode)[0].data;
var range = selection.getRangeAt(0);
range.deleteContents();
};
Upd.
The EditorName is a var with the id of the editor. For simplicity, I updated the code to use the name directly.
Here is the html:
<div id="wrapper">
<main data-ng-controller="HomeCtrl as HomeCtrl">
<div id="Editor" contenteditable="true"></div>
</main>
<div id="PushFooter"></div>
</div>
Fiddle: https://jsfiddle.net/720fg8ne/
Expected behaviour would be: typing in text->pressing tab-> the text should disappear
Second line of your javascript code is wrong, editorName must be a string:
var el = document.getElementById('EditorName');
Text variable looks like a mix of vanilla js and jQuery, I fix it here:
let text = selection.anchorNode.data;
All code fixed:
var parseLine = function() {
var el = document.getElementById('EditorName');
var selection = window.getSelection();
let text = selection.anchorNode.data;
var range = selection.getRangeAt(0);
range.deleteContents();
};
Related
HTML:
<textarea id="text-box" size="20"></textarea>
<button onclick="selectText()">Get Content</button>
JavaScript:
function selectText() {
var txtArea = document.getElementById('text-box');
txtArea.value = "Some Text";
txtArea.focus();
console.log(txtArea.value.length)
var sel = window.getSelection();
var range = sel.getRangeAt(0);
console.log('range.collapsed',range.collapsed)
range.collapse(true);
}
The above code indicates that the range is already collapsed, and the newly set content isn't selected. The cursor is at the end of the content. I want the cursor to be set to the beginning of the content. If I set the selection to the entire content, and then try to collapse it, the following code doesn't work.
Tried:
function selectText() {
var txtArea = document.getElementById('text-box');
txtArea.value = "Some Text";
txtArea.focus();
console.log(txtArea.textContent.length)
txtArea.setSelectionRange(0, txtArea.value.length);
var sel = window.getSelection();
console.log(sel.rangeCount)
sel.collapseToStart();//Doesn't work
//Also tried the following
//var range = sel.getRangeAt(0);
//range.collapse(true);
}
I try the code sel.collapseToStart() and its work fine. So maybe its a compatibility issues. What browser do you use?
https://codepen.io/gwtjs/pen/qzrJbp
I'm having problems running an action on more than one line.
In practice I do not get the desired effect and <p> tags are completely emptied of their content. This is the simple code I use, but it only works on a line:
Try to look at code in action HERE .
Follow the instructions in the example to understand the real problem.
function press() {
if (document.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount < 1) {
return;
}
var r = window.getSelection().getRangeAt(0);
var selectedText = r.toString(),
content = r.extractContents();
span = document.createElement('span'),
t = document.createTextNode(selectedText);
selectedText = '';
span.style.color = 'green';
span.appendChild(t);
r.insertNode(span);
window.getSelection().removeAllRanges();
}
}
<p>Select only me for first: i don't have problems</p>
<p>Also select me at the same time of first paragraph, now i have problems..</p>
<button onclick="press()">Press after selecting the text</button>
I'd like to select text within a content editable div. I'd like to provide a start index and an end index.
For example if I have a div:
<div id="main" contenteditable="true">
Hello World
</div>
I'd like a function to do something like "selectText('#main',6,10)" and it would select set the focus to main and select "World".
But all the examples that I see online assume that the container div has children. But mine don't have any children. Just the text within the div.
This is what I've tried so far to no avail:
$('#main').focus();
var mainDiv = document.getElementById("main");
var startNode = mainDiv;
var endNode = mainDiv;
var range = document.createRange();
range.setStart(startNode, 6);
range.setEnd(endNode, 10);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
But I get:
Uncaught IndexSizeError: Failed to execute 'setStart' on 'Range': There is no child at offset 6.
My jsfiddle:
http://jsfiddle.net/foreyez/h4bL5u4g/
But mine don't have any children. Just the text within the div.
The text within the div is a child – it's a text node. That's what you want to target.
You will also need to trim its nodeValue to get the proper offset. Otherwise, the leading spaces will be included.
This seems to do what you want:
function SelectText(obj, start, stop) {
var mainDiv = $(obj)[0],
startNode = mainDiv.childNodes[0],
endNode = mainDiv.childNodes[0];
startNode.nodeValue = startNode.nodeValue.trim();
var range = document.createRange();
range.setStart(startNode, start);
range.setEnd(endNode, stop + 1);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} //SelectText
$('#main').focus();
SelectText('#main', 6, 10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main" contenteditable="true">
Hello World
</div>
How can I add <span> tags around selected text within an element?
For example, if somebody highlights "John", I would like to add span tags around it.
HTML
<p>My name is Jimmy John, and I hate sandwiches. My name is still Jimmy John.</p>
JS
function getSelectedText() {
t = (document.all) ? document.selection.createRange().text : document.getSelection();
return t;
}
$('p').mouseup(function(){
var selection = getSelectedText();
var selection_text = selection.toString();
console.log(selection);
console.log(selection_text);
// How do I add a span around the selected text?
});
http://jsfiddle.net/2w35p/
There is a identical question here: jQuery select text and add span to it in an paragraph, but it uses outdated jquery methods (e.g. live), and the accepted answer has a bug.
I have a solution. Get the Range of the selecion and deleteContent of it, then insert a new span in it .
$('body').mouseup(function(){
var selection = getSelectedText();
var selection_text = selection.toString();
// How do I add a span around the selected text?
var span = document.createElement('SPAN');
span.textContent = selection_text;
var range = selection.getRangeAt(0);
range.deleteContents();
range.insertNode(span);
});
You can see the DEMO here
UPDATE
Absolutly, the selection will be delete at the same time. So you can add the selection range with js code if you want.
You can simply do like this.
$('body').mouseup(function(){
var span = document.createElement("span");
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0).cloneRange();
range.surroundContents(span);
sel.removeAllRanges();
sel.addRange(range);
}
}
});
Fiddle
Reference Wrapping a selected text node with span
You can try this:
$('body').mouseup(function(){
var selection = getSelectedText();
var innerHTML = $('p').html();
var selectionWithSpan = '<span>'+selection+'</span>';
innerHTML = innerHTML.replace(selection,selectionWithSpan);
$('p').html(innerHTML);
});
and In your fiddle you are again opening a new <p> instead of a closing </p>. Update that please.
THIS WORKS (mostly*)!! (technically, it does what you want, but it needs HALP!)
JSFiddle
This adds <span ...> and </span> correctly, even if there are multiple instances of the selection in your element and you only care about the instance that's selected!
It works perfectly the first time if you include my commented line. It's after that when things get funky.
I can add the span tags, but I'm having a hard time replacing the plaintext with html. Maybe you can figure it out? We're almost there!! This uses nodes from getSelection. Nodes can be hard to work with though.
document.getElementById('d').addEventListener('mouseup',function(e){
var s = window.getSelection();
var n = s.anchorNode; //DOM node
var o = s.anchorOffset; //index of start selection in the node
var f = s.focusOffset; //index of end selection in the node
n.textContent = n.textContent.substring(0,o)+'<span style="color:red;">'
+n.textContent.substring(o,f)+'</span>'
+n.textContent.substring(f,n.textContent.length);
//adds the span tag
// document.getElementById('d').innerHTML = n.textContent;
// this line messes stuff up because of the difference
// between a node's textContent and it's innerHTML.
});
I need to know if there is a "span" in my extracted content.
Simple js part, getting selection from textarea:
...
selection = this.getWin().getSelection().getRangeAt(0);
content = selection.extractContents();
alert(content)// this gets documentFragment
alert(content.firstChild)//null
fontEl = document.createElement ("span")
fontEl.appendChild(content);
alert(fontEl.outerHTML)// works ok. but now i have 2 spans if there was one before append
there is my jsfiddle. i test changing the font-size. it works, but it is spamming spans because of this problem.
http://jsfiddle.net/DCGRg/73/
Your code isn't far off. Here's an updated demo:
http://jsfiddle.net/DCGRg/73/
Here's the relevant piece of code:
var font_size = combo.getValue();
var selection = this.getWin().getSelection();
if (selection.rangeCount > 0) {
var range = selection.getRangeAt(0);
var content = range.extractContents();
var fontEl = this.getWin().document.createElement("span");
fontEl.style.fontSize = font_size + 'px';
fontEl.appendChild(content);
range.insertNode(fontEl);
selection.selectAllChildren(fontEl);
}