I'm trying to replace selected text with another text with a function switchText called from the context menu.
function switchText(info) {
var text = info.selectionText; // selected text
// then I do some manipulations with 'text' and get 'text_to_replace'
var text_to_replace = "some text"; // text to replace
}
alert(text) and alert(text_to_replace) works fine, but I'm trying to replace selected text right on the page but I can't figure out how to do it. I tried different methods but they hadn't worked. Any special permissions needed? I'm sorry if it's stupid question, I'm beginner in JS.
If you want to be able to do this anywhere on a page, you need to be able to set some kind of identifying ID to your selection. You have to do this through a content script of some kind. You can read more about it in the Chrome Developer documentation.
This code will allow you to change the text of a single selection
(tested in Chrome only)
function switchText(id) {
// Gets the selection range
// This is from Tim Down, linked below
var range, sel = window.getSelection();
if (sel.rangeCount && sel.getRangeAt) {
range = sel.getRangeAt(0);
}
// Creates a new node range
document.designMode = "on";
if (range) {
sel.removeAllRanges();
sel.addRange(range);
}
// This is from user YeppThatsMe, also linked below
document.execCommand("insertHTML", false, "<span id='own-id'>"+ document.getSelection()+"</span>");
document.designMode = "off";
// You can use either a variable or a string
var someNewText = "-- You can make this whatever you want --";
// Finds the new span and replaces the selection with your new text
document.getElementById("own-id").innerHTML=someNewText;
};
Sourced scripts
Tim's script
HTML5 inserCommand
Last Note
I didn't spend too long testing, and the script as-is will only change one selection per page. You'll need to tweak the way the function gets the tag and attribute info (change it to getElementsByClassName?) to run it more than once, but this should work.
to update a html element targeted by Id
document.getElementById("idtotarget").innerHTML = switchText(document.getElementById("idtotarget").innerHTML)
Related
I have been trying to build a web based text editor. And as part of the process, I am trying to dynamically create and modify elements based and keystroke events for font editing. In this particular jsfiddle example I'm trying to create a strong element upon hitting CTRL+b and setting the focus/caret inside the strong element so that subsequent text entered will be part of the bold element and hence will have bold text. But my code is just creating a strong element but not transferring the focus hence no text is getting bolder.
In the below code I'm creating event listener to capture keystroke events
p=document.getElementsByTagName("p")[0];
//console.log(p)
// adding eventlistener for keydown
p.addEventListener("keydown",listener);
// eventlistenerr callback function
function listener(){
e=window.event;
if(e.ctrlKey && e.keyCode==66)
{
console.log("CTRL+B");
// creating bold element
belm=document.createElement("strong");
belm.setAttribute("contenteditable","true")
p.appendChild(belm);
//bug below
// setting focus inside bold element
setfocus(belm,0);
e.preventDefault();
}
}
Here is the function for setting the focus.
function setfocus(context, position){
var range = document.createRange();
position =position || 0;
var sel = window.getSelection();
range.setStart(context, position);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
context.focus();
}
However, I have not doubt that the function which sets focus is faulty, because in the fiddle if you observe, I have created a separate setup just to test this
out. Click on the button "Click Here" and the focus dynamically shifts to paragraph element without any hassle. I am unable to figure out what is going wrong.
It's pretty much impossible to move the cursor into an empty element in a contenteditable div. However, as shay levi suggested in another post, you can insert the zero-width character ÈB into your empty element to give it an index value.
Here's an example*:
function insertNode(nodeName) {
var sel = window.getSelection(),
range;
range = sel.getRangeAt(0);
range.deleteContents();
var child = document.createElement(nodeName);
child.innerHTML = '';
range.insertNode(child);
}
var div = document.querySelector('div'),
btn = document.querySelector('button');
btn.addEventListener('click', function() {
insertNode('strong');
div.focus();
});
div.focus();
<div contenteditable></div><button><strong>B</strong></button>
*For the sake of simplicity, this script doesn't toggle bold text, it only sets it.
I am trying to include functionality that will enable a user to highlight text and have that text returned. I would also like to return the location of that text within #textcontainer div.
My issue: if the user highlights the second 'and' in the text below, position will equal the indexOf the first 'and' in the div instead of the second. How do I change this to have position return the position of the second 'and' (the one that is highlighted)?
<div id = 'textcontainer'>
and second third and
</div>
// beginning of highlight js
$('#highlight').click(function (e) {
e.preventDefault();
// get highlighted text
var selection = window.getSelection();
var txt = selection.toString();
console.log(txt);
fulltext = $("#textcontainer").text();
console.log(fulltext);
position = fulltext.indexOf(txt);
console.log(position);
})
// end of highlight js
You're in luck, since window.getSelection() returns a Selection object, which in turn has a getRangeAt method, which you can use like so:
var selection = window.getSelection();
var range = selection.getRangeAt(0);
var start = range.startOffset, end = range.endOffset;
Edit: Note that IE has a completely different selection API. For cross-browser compatibility, you may want to take a look at Rangy (note: I don't have any experience with the library).
Edit 2: See this answer for some jQuery plugins.
I'm tweaking a wysiwyg editor, and I'm trying to create an icon which will strip selected text of h2.
In a previous version, the following command worked perfectly:
oRTE.document.execCommand("removeformat", false, "");
But in the current version, although that command successfully removes from selected text such tags as bold, underline, italics, it leaves the h2 tag intact.
(Interestingly enough, execCommand("formatblock"...) successfully creates the h2 tag.)
I'm thinking that I'm going to have to abandon execCommand and find another way, but I'm also thinking that it will be a lot more than just 1 line of code! Would be grateful for suggestions.
You can change your format to div, it's not the best solution but it works and it's short:
document.execCommand('formatBlock', false, 'div')
There is also this other solution to get the closest parent from selected text then you can unwrap it, note that this can be some tag like <b>:
var container = null;
if (document.selection) //for IE
container = document.selection.createRange().parentElement();
else {
var select = window.getSelection();
if (select.rangeCount > 0)
container = select.getRangeAt(0).startContainer.parentNode;
}
$(container).contents().unwrap(); //for jQuery1.4+
This is in accordance with the proposed W3C Editing APIs. It has a list of formatting elements, and the H# elements are not listed. These are considered structural, not simply formatting. It doesn't make any more sense to remove these tags than it would to remove UL or P.
I think you can use the Range object.
you can find it from Professional JavaScript for Web Developers 3rd Edition.
chapter 12(12.4) and chapter 14(14.5) ...
an example from that book:
var selection = frames["richedit"].getSelection();
var selectedText = selection.toString();
var range = selection.getRangeAt(0);
var span = frames["richedit"].document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);
I need to get the position of the selected text within a content non-editable div (not a textarea, not a rtf editor, just a simple div)
I want to do this in order to enable users to select pieces of an article and "highlight it", by wrapping it in a span with a different background and, of course, an article is build with divs and/or p-s etc, not textareas or rtfs
Any ideas?
P.s. You can also use jQuery :D
P.s.s. I need the position of the selection, not the selection itself. Aka: it start from index I to index J. I need this because the normal method of finding the text in the parent does not always return a unique result, which would suck :)
If you just want to change the background of the selected text, the easiest way to do this is by using document.execCommand(). See my answer here: Change CSS of selected text using Javascript
//Wrap selected text in span tags with the class 'hl'
//Take some action after (in this case, a simple alert)
$("p").live("mouseup",
function() {
selection = getSelectedText();
if(selection.length >= 3) {
$(this).html($(this).html().replace(selection, $('<\/span>').attr({'class':'hl'}).html(selection).parent().html()) );
alert(selection);
}
}
);
//Grab selected text
function getSelectedText(){
if(window.getSelection){
return window.getSelection().toString();
}
else if(document.getSelection){
return document.getSelection();
}
else if(document.selection){
return document.selection.createRange().text;
}
}
Code comes from here: http://esbueno.noahstokes.com/post/92274686/highlight-selected-text-with-jquery
You can check if text is selected by running :
window.getSelection and document.getSelection() and document.selection
(because browsers can check this i different ways)
and then search for div containing this text .
For getting the position of the selection, try these links:
http://bytes.com/topic/javascript/answers/153164-return-selectionstart-div
Set cursor position on contentEditable <div>
Well, even though you found a solution to the problem stated in your 2nd paragraph, i don't think the answer to your main question has been given. :)
The object Selection has a property named anchorOffset, giving exactly what you asked for (the position of the selected text within an element). The above link will tell you about which browsers support it, i'm afraid IE <9 might not.
function show_selected()
{
var sel = selection();
console.log(sel.anchorOffset + ':' + sel);
}
Now if you bind show_selected to, say, mouseup, you will see the offset and the selected text printed on the js console.
The fonction selection may be the following, supposed to be cross-browser:
function selection()
{
var sel;
if(window.getSelection){
sel = window.getSelection()
}
else if(document.getSelection){
sel = document.getSelection()
}
else if(document.selection){
sel = document.selection.createRange()
}
return sel
}
I have a UIWebView i want to introduce functionality of content(may be text or text and images) selection so that the user can email it.
Is there any way to get the HTML code for the given selection using JavaScript?
I tried the built-in clipboard of webkit but its seems not working for images selection.May be i am wrong,if there is a way please tell me.
var range, frag, sel = window.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0);
frag = range.cloneContents();
}
This will give you a DocumentFragment containing the selected content. You can traverse the descendants of the fragment using the usual DOM methods. If you must have a literal HTML string, you could then do the following:
var div = document.createElement("div");
div.appendChild(frag);
alert(div.innerHTML);
Note that this last part won't work if the selected contents can't be placed inside a <div> (if, say, the whole body or document was selected).