mpen
mpen

Reputation: 282885

Turn an anchor into a span?

What's the easiest way to turn an <a> into <span> keeping all the attributes and content? (except for perhaps the href).

.replaceWith() replaces the whole shebang.

Upvotes: 3

Views: 1346

Answers (3)

calebds
calebds

Reputation: 26228

Combine jQuery's replaceWith() and html() and copy attributes iteratively. Given your anchor tag has id #anchor:

$('#anchor').replaceWith(function() {
    var span = $('<span/>');
    $.each(this.attributes, function(){
        span.attr(this.name, this.value);
    });
    return span.html($(this).html());            
});

See updated jsFiddle for an example.

Upvotes: 1

gilly3
gilly3

Reputation: 91497

You can iterate an element's attributes using the attributes property. You can copy an attribute using attribute.cloneNode(true). You can add that cloned attribute to another element's attributes collection with element.attributes.setNamedItem(attribute).

Here's a quick plugin that does it:

$.fn.cloneTo = function (target) {
    // copies the attributes, html, and event handlers of the first element to each of
    // the elements in the provided jQuery object or that match the provided selector
    if (!target || !target.jquery) {
        target = $(target);
    }
    if (this.length) {
        $.each(this[0].attributes, function(i, attr) {
            target.each(function(){
                this.attributes.setNamedItem(attr.cloneNode(true));
            });
        });
        $.each(this.data("events"), function(evt, handlers){
            $.each(handlers, function(i, handler){
                target.bind(evt, handler);
            });
        });
        target.empty().append(this.contents());
    }
    return this;
};

Use it like this:

var span = $("<span>");
$("#myLink").cloneTo(span).replaceWith(span);

Working demo: http://jsfiddle.net/gLqZJ/2

Edit: Updated above to copy event handlers and to keep the descendent nodes untouched, rather than duplicating the HTML.

Upvotes: 3

Bergi
Bergi

Reputation: 664548

How about

$element.html(function(html) {
   return html.replace(/<(\/?)a/gi, "<$1span"); // string manipulation might be faster, but you get the concept
});

That would save the attributes and content, but not any data and event handlers. If you need those for the descendants, you should remove the child nodes and append them to the new span.

EDIT: Sorry, I'm not that familiar with jQuery. The .html() method changes the innerHTML, not including the node itself. The function should be something like:

$element(s).each(function() {
   var l = this.tagName.length + 1;
   this.outerHTML = "<span"+this.outerHTML.slice(l, -l)+"span>";
});

Upvotes: 2

Related Questions