I know how to set an <a />
tag with the href
attribute in a contenteditable
like this:
execCommand("CreateLink", false, "#jumpmark");
which will result in
<a href="#jumpmark">selection</a>
However I cannot figure out how to set an anchor name
instead of the href
.
This is my desired result:
<a name="jumpmark">selection</a>
Can anyone help me?
Side notes: I am using jQuery and Rangy as libraries, however I would prefer a solution that works directly with execCommand.
Update: Here's a jsfiddle: / Select some text and click the button. All I want is that with the button click a link is inserted with a name attribute set instead of the href.
I know how to set an <a />
tag with the href
attribute in a contenteditable
like this:
execCommand("CreateLink", false, "#jumpmark");
which will result in
<a href="#jumpmark">selection</a>
However I cannot figure out how to set an anchor name
instead of the href
.
This is my desired result:
<a name="jumpmark">selection</a>
Can anyone help me?
Side notes: I am using jQuery and Rangy as libraries, however I would prefer a solution that works directly with execCommand.
Update: Here's a jsfiddle: http://jsfiddle/fjYHr/ Select some text and click the button. All I want is that with the button click a link is inserted with a name attribute set instead of the href.
Share Improve this question edited Dec 19, 2012 at 9:21 Horen asked Dec 19, 2012 at 9:02 HorenHoren 11.4k12 gold badges76 silver badges116 bronze badges 9-
I'm guessing
execCommand
is something of "Rangy" (don't know what that is). Couldn't you just use jQuery's.attr("name", "jumpmark")
to do that? – Ian Commented Dec 19, 2012 at 9:04 -
1
No the
execCommand
is a browser mand which enables you to change content incontenteditable
elements. See quirksmode/dom/execCommand.html for an explanation – Horen Commented Dec 19, 2012 at 9:06 -
2
Can't believe I've never seen that before. Is it necessary to use
execCommand
? Why couldn't you use jQuery (or plain Javascript) to create the element, set its attribute, and then append it to the DOM where you want? – Ian Commented Dec 19, 2012 at 9:09 - because I need to work on the current selection. Specifically I don't have a jQuery object that I can append to, meaning I don't have a DOM node that I can work on. – Horen Commented Dec 19, 2012 at 9:11
-
What do you mean the "current selection". You don't need jQuery objects or whatever, forget I said that. Just think of the normal way you add elements to the page with Javascript - use
createElement
, set its attribute, append to DOM. I guess I still don't understand why it's necessary to useexecCommand
– Ian Commented Dec 19, 2012 at 9:13
3 Answers
Reset to default 2You could use something like the following, which is adapted from the pasteHtmlAtCaret()
function from this answer of mine:
Demo: http://jsfiddle/F8Zny/
Code:
function surroundSelectedText(element) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
element.appendChild( document.createTextNode(range.toString()) );
range.deleteContents();
range.insertNode(element);
// Preserve the selection
range = range.cloneRange();
range.setStartAfter(element);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
var selRange = document.selection.createRange();
element.appendChild( document.createTextNode(selRange.text) );
selRange.pasteHTML(element.outerHTML);
}
}
If you must use document.execCommand()
then you could use the InsertHTML
mand in non-IE browsers. However, IE does not support it.
document.execCommand("InsertHTML", false, '<a name="jumpmark">selection</a>');
I see you're using Rangy, but I don't how to use it at all. Before I realized what Rangy was, I looked up how to get the current selection. I found a function that gets it and replaces it with a passed in value. I ended up modfiying it, but here it is:
http://jsfiddle/fjYHr/1/
$(document).ready(function () {
$("#setlink").click(function () {
replaceSelectedText("jumplink");
});
});
function replaceSelectedText(nameValue) {
var sel, sel2, range;
if (window.getSelection) {
sel = window.getSelection();
sel2 = ""+sel; // Copy selection value
if (sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
var newA = document.createElement("a");
newA.name = nameValue;
newA.innerHTML = sel2;
range.insertNode(newA);
}
} else if (document.selection && document.selection.createRange) {
// Not sure what to do here
range = document.selection.createRange();
var newA = "<a name='" + nameValue.replace(/'/g, "") + "'>" + range.text + "</a>";
range.text = newA;
}
}
Notice how I store the original current selection, then replace it with an <a>
element that gets its name
set with the passed-in value.
As for the document.selection
part (which seems to be used by IE < 9), I'm not 100% sure that the code I provided will work (actually allow HTML in the selection, and not escaping it). But it's my attempt :)
As you've seen execCommand
is rather limited in the attributes you can set, as such you cannot set the name
attribute using it - only the href
.
As you have jQuery
set as a tag, you can use that as an alternative:
var $a = $('<a></a>').attr('name', 'jumpmark').appendTo('body');
Update
I need to work on the current selection. Specifically I don't have a jQuery object that I can append to, meaning I don't have a DOM node that I can work on
In this case use a plugin such as Rangy to get the selection which you can then amend with jQuery as required.