JavaScript / jQuery: how to get selected text in Firefox [duplicate] - javascript

This question already has answers here:
window.getSelection() of textarea not working in firefox?
(2 answers)
Closed 3 months ago.
How can I get the selected text (in a contenteditable div) in Firefox ? It would be enough for recent versions, no need to cover old versions.
Say I have a contenteditable div that looks like the below and someone selects a text there and then hits a button, how can I copy the selected text to the clipboard or a variable ?
Example:
<div class='editInput' id='editInput'>Some awesome text</div>
My current function (working in IE):
function GetSelection()
{
if (typeof window.getSelection != "undefined")
{
var sel = window.getSelection();
if (sel.rangeCount)
{
var container = document.createElement('div');
for (var i = 0, len = sel.rangeCount; i < len; ++i)
container.appendChild(sel.getRangeAt(i).cloneContents());
return container.innerHTML;
}
}
else if (typeof document.selection != 'undefined')
if (document.selection.type == 'Text')
return document.selection.createRange().htmlText;
return '';
}

var selectedText = "" + window.getSelection();

The other suggestions didn't work for me, but the following did:
var textArea = document.getElementById('input_text_area');
var selectedText = textArea.value.substring(textArea.selectionStart,textArea.selectionEnd);
This other answer links to some background on why the above is necessary and why window.getSelection() doesn't work on Firefox, for example.

Related

getSelection is not working for an image in Chrome

In my site I am using a WYSIWYG editor that uses an iframe.
When I select a text with double click in order to add a link to it, in Chrome, Safari and Firefox the selected text is the right one and the link is added.
However, when I click an image instead, the selection is done only in Firefox. Chrome and Safari have an empty selection and in order to select the image and add a link on it, I have to drag the mouse over it, like a manual select.
My code is:
var sel = parent.document.getElementById('myframe').contentWindow.document.getSelection();
if (sel.rangeCount > 0) {
var range = sel.getRangeAt (0);
var docFragment = range.cloneContents ();
var tmpDiv = document.createElement ("div");
tmpDiv.appendChild (docFragment);
selHTML = tmpDiv.innerHTML;
}
if (selHTML != '') {
parent.document.getElementById('myframe').contentWindow.document.execCommand(id,false,value);
}
Is there any way to solve this problem?
Thanks in advance.
I change the code to that one according to #Tim suggestions:
var iframeWin = parent.document.getElementById('myframe').contentWindow;
var iframeDoc = iframeWin.document;
var sel = iframeWin.getSelection();
var range = iframeDoc.createRange();
var referenceNode = document.getElementsByTagName("img").item(0);
range.selectNode(referenceNode);
sel.removeAllRanges();
sel.addRange(range);
parent.document.getElementById('myframe').contentWindow.document.execCommand(id,false,value);
But still not works. Any more suggestions?
You could just do this manually using the dblclick event, but beware of breaking the regular image resize handles you get in non-WebKit browsers.
Live demo: http://jsfiddle.net/x49hv/3/
Code:
var iframeWin = parent.document.getElementById('myframe').contentWindow;
var iframeDoc = iframeWin.document;
// Prevent errors in IE < 9, which does not support DOM Range and Selection
if (iframeWin.getSelection && iframeDoc.createRange) {
iframeDoc.ondblclick = function(e) {
if (e.target.nodeName.toLowerCase() == "img") {
var sel = iframeWin.getSelection();
var range = iframeDoc.createRange();
range.selectNode(e.target);
sel.removeAllRanges();
sel.addRange(range);
}
};
}

insert text before and after at selected text [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Insert text before and after the selected text in javascript
I want to put some specified text (where possible in iframe when designmode on) before and after any selected text in an HTML document. document.getSelection() or document.selection.createRange().text returns only the text itself not the position.
Is there anyway to replace the selected text?
Anyway to insert specific text before and after selcted text anywhere in the document?
I answered a related question of yours earlier today:
https://stackoverflow.com/a/8740153/96100
Also, here's an answer I posted to a remarkably similar question a year ago, recently updated to work in IE 9:
https://stackoverflow.com/a/4770592/96100
Finally, here's a version of the function from the second linked answer for your editable iframe. It allows you specify a document object:
function insertHtmlAtSelectionEnd(html, isBefore, doc) {
doc = doc || document;
var win = doc.defaultView || doc.parentWindow;
var sel, range, node;
if (win.getSelection) {
sel = win.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.collapse(isBefore);
// Range.createContextualFragment() would be useful here but was
// until recently non-standard and not supported in all browsers
// (IE9, for one)
var el = doc.createElement("div");
el.innerHTML = html;
var frag = doc.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
}
} else if ( (sel = doc.selection) && sel.type != "Control") {
range = sel.createRange();
range.collapse(isBefore);
range.pasteHTML(html);
}
}

How to find if a HTMLElement is enclosed in Selected text

Is it possible to find out if an HTMLElement is totally enclosed within the selection?
I have a scenario where user selects some text in a HTML editor and applies some custom style from a list. Now I need to change the class attribute of each span element that is enclosed in that selection and surrounding the selection with a new span with the selected style.
Am able to find out if a particular span element is in selection by using DOM Range's compareBoundaryPoints method in firefox and safari but it will not work for IE.
Is there any way to find out if an element is totally enclosed with in the selected range for IE?
Thanks
Kapil
As #standardModel says, Rangy gives you full* DOM Range support in IE and has a helpful getNodes() method that you could use:
var sel = rangy.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0);
var spans = range.getNodes([1], function(node) {
return node.nodeName.toLowerCase() == "span" && range.containsNode(node);
});
// Do stuff with spans here
}
If you'd rather not use something as bulky as Rangy, the following function will tell you if an element is completely selected:
function isSelected(el) {
if (window.getSelection) {
var sel = window.getSelection();
var elRange = document.createRange();
elRange.selectNodeContents(el);
for (var i = 0, range; i < sel.rangeCount; ++i) {
range = sel.getRangeAt(i);
if (range.compareBoundaryPoints(range.START_TO_START, elRange) <= 0
&& range.compareBoundaryPoints(range.END_TO_END, elRange) >= 0) {
return true;
}
}
} else if (document.selection && document.selection.type == "Text") {
var textRange = document.selection.createRange();
var elTextRange = textRange.duplicate();
elTextRange.moveToElementText(el);
return textRange.inRange(elTextRange);
}
return false;
}
jsFiddle example: http://jsfiddle.net/54eGr/1/
(*) Apart from handling Range updates under DOM mutation
You may want to take a look at Rangy. This makes xbrowser Ranges and Selections a lot easier.

Javascript: Get Selected Text From Textarea in IE8

I'm trying to read in the value of selected text within a text area. Here is my code:
function readSelected(id)
{
textarea = document.getElementById(id);
if (document.selection)
{ //Code for IE
textarea.focus();
sel = document.selection.createRange();
alert(sel.text);
}
else
{ // Code for Mozilla Firefox
var len = textarea.value.length;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var scrollTop = textarea.scrollTop;
var scrollLeft = textarea.scrollLeft;
sel = textarea.value.substring(start, end);
alert(sel);
}
}
HTML:
<textarea id="txt1" rows="10"></textarea>
<a onclick="readSelected('txt1');">Get Selected</a>
When you click the button, a popup should occur telling you what the selected text is.
The code works in Firefox, but I can't get it to work in IE8.
The problem is that clicking on the <a> element destroys the selection. You could use an unselectable button instead:
<input type="button" value="get" onclick="readSelected('txt1');" unselectable="on">
There are other minor issues with your code
You should declare all your variables, otherwise they end up leaking into the global scope. sel and textarea are the offenders here.
scrollTop and scrollLeft are redundant.
You should test for the selectionStart and selectionEnd properties first, since they're the standard (HTML 5 specifies them and IE 9 will support them).
Here's my rewritten version:
function readSelected(id) {
var sel = "", el = document.getElementById(id);
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
sel = el.value.slice(el.selectionStart, el.selectionEnd);
} else if (document.selection && document.selection.createRange) {
el.focus();
sel = document.selection.createRange().text;
}
alert(sel);
}
Did you try with onmousedown instead of onclick ?

Javascript: get html around user selection?

It is possible to get whatever the user has selected with the mouse using Javascript, like this: http://www.motyar.info/2010/02/get-user-selected-text-with-jquery-and.html
My issue is that I do not just need this text, but I also need:
to get the html surrounding this text (eg. if the user selects "hello" and this hello is in the source produced as: "<div><span>hello</span></div>" that is what it should return).
to do the same for graphics
Can anyone guide me through this process, or are there alternatives if this is not possible?
This will do it in all major browsers. There are separate branches for IE and more standards-compliant browsers. In IE, it's slightly easier because the proprietary TextRange object created from the selection has a handy htmlText property. In other browsers, you have to use the cloneContents() method of DOM Range to create a DocumentFragment containing a copy of the selected content and obtain the HTML from this by appending the fragment to an element and returning the element's innerHTML property.
function getSelectionHtml() {
var html = "";
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
if (sel.rangeCount) {
var container = document.createElement("div");
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
container.appendChild(sel.getRangeAt(i).cloneContents());
}
html = container.innerHTML;
}
} else if (typeof document.selection != "undefined") {
if (document.selection.type == "Text") {
html = document.selection.createRange().htmlText;
}
}
return html;
}
alert(getSelectionHtml());
You can also do like this to get user selected HTML
function getUserSelectedHtml() {
const range = window.getSelection().getRangeAt(0);
const node = document.createElement('div');
node.appendChild(range.cloneContents());
return node.innerHTML;
}

Categories