Milanzor
Milanzor

Reputation: 1930

How to get an element and all attributes as a string in Javascript/jQuery

I'm looking for a native/jQuery method to return an elements opening tag with all its attributes and their values as a string.

It should look something like this.

HTML:

<body id="mybody" class="someclass">

</body>

Non-existing jQuery function:

$("body").tagAsString(); //returns <body id="mybody" class="someclass">

or non-existing native function:

document.getElementsByTagName("body")[0].tagToString();

I can get all attributes of an element with their values, but I need the exact string as it is just in the HTML. Looking for the length of the whole opening tag.

Upvotes: 1

Views: 1963

Answers (4)

Lior
Lior

Reputation: 40649

it's better to avoid parsing yourself. you might want to look at https://unifiedjs.com/ - a lot of plugins to do parsing related work.

Upvotes: 0

Alnitak
Alnitak

Reputation: 339786

Given the information just supplied in the comments describing the actual problem you're trying to solve, you don't need to retrieve the body tag's attributes at all, and nor should you be using string searching. Just do:

var $newContent = $('<div>' + data + '</div>').children();
$(document.body).empty().append($newContent);

i.e. parse the entire data - $(data) - then get all child nodes, and put those in your existing document.body.

The <div> + data + </div> is necessary because $(html) requires a single element (and children) and won't accept the standard HTML boilerplate of <!DOCTYPE ...><html>...</html>. It also appears to strip out the <head> and <body> tags, leaving behind only their children. In tests I've just made, given

var data = '<!doctype html><html><head></head><body><span>Test</span>' +
           '<span>Test 2</span></body></html>'

then

$('<div>' + data + '</div>').children()

gives just the two <span> elements, i.e. the desired contents of data's <body> tag.

EDIT OK - it seems that doesn't quite work out as desired because of the stripping of the <head> and <body> tags, leaving the original contents of the <head> in place.

Try this, instead - it's a combination of your original technique, and this one:

var $newContent = $(data.substring(data.indexOf('<body')));
$(document.body).empty().append($newContent);

Upvotes: 2

Damian Drygiel
Damian Drygiel

Reputation: 18028

<body id="mybody" class="someclass">
    blah blah...
</body>

To get what you want use this:

As @lonesomeday mentioned not all browsers support outerHTML so you have to use your own implementation of it:

jQuery.fn.outerHTML = function() {
    return $("<p>").append(this.eq(0).clone()).html();
};

And then use it to receive what you want:

var html = $(document.body).outerHTML(),
    html = html.substr(0, html.indexOf('>')+1);

So html variable contains <body id="mybody" class="someclass">

Upvotes: 1

lonesomeday
lonesomeday

Reputation: 237845

The problem is that, once the HTML has been parsed, the browser doesn't care about it any more. The DOM structure that the browser has interpreted is all that matters. The HTML is gone. Kaput. Finished. Ignored.

How the browser thinks of the HTML after parsing it.

The browser does not keep the "original HTML" in any way. In fact, the browser doesn't really like HTML. It's not how it thinks, and converting things to HTML can be a bit tricky.

All you can get is a representation of how the browser currently has the element. This may well not be the same as the HTML. For instance, any attributes that have been changed in the DOM will appear differently to the original HTML.

The process might look like this:

var html = $(document.body)
    .clone() // get a copy of the element to work on
    .empty() // empty it
    .appendTo('<div/>').parent().html(); // equivalent to outerHTML

This gives a result like:

'<body class="question-page"></body>'

You could then remove everything from the final <:

html = html.substr(0,html.lastIndexOf('<'));

Which gives:

'<body class="question-page">'

Upvotes: 4

Related Questions