最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Set anchor name with execCommand - Stack Overflow

programmeradmin2浏览0评论

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 in contenteditable 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 use execCommand – Ian Commented Dec 19, 2012 at 9:13
 |  Show 4 more ments

3 Answers 3

Reset to default 2

You 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.

发布评论

评论列表(0)

  1. 暂无评论