Reputation: 7192
I wonder if there's any way to get the JS code of an existing HTML element using any existing method. I am trying to print the code generator of any DOM element, so when the user clicks on any HTML element of the webpage, a message will be shown with the source code to create that element in Javascript.
For example, I have a Div created:
var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover=function(){div.style.color = "red"};
div.innerHTML = "I'm the div";
And then I was trying to obtain the source code, but:
document.body.appendChild(div.innerHTML);
This option only writes the textual content: "I'm the div". SO I tryed:
document.body.appendChild(div.outerHTML);
But it writes the HTML code without the onmouseover function: "I'm the div"
What I really need is to show this code (or something similar):
var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover=function(){div.style.color = "red"};
div.innerHTML = "I'm the div";
Do you have any idea where can I start reading? Thanks a lot,
Upvotes: 3
Views: 305
Reputation: 5140
If you have control over the creation of the elements you could ensure that each element is created in it's own separate function. Then a simple function can get the function body.
function createElement1() {
var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover=function(){div.style.color = "red"};
div.innerHTML = "I'm the div";
}
function getFunctionBody(func) {
var functionText = func.toString();
return functionText.slice(functionText.indexOf("{") + 1, functionText.lastIndexOf("}"));
}
Here's a working example. http://jsfiddle.net/C5b7n/
Upvotes: 0
Reputation: 32912
outerHTML
is a good choice with several limitations:
In other words, IDL attributes are ignored, only content attributes are serialized.
Events by IDL attributes are coded as
div.onmouseover=function(){div.style.color = "red"};
div.addEventListener("mouseover",function() {div.style.backgroundColor="blue";});
See more about events
Whereas events by content attributes are coded as
div.setAttribute("onmouseover","this.style.color='red'");
Using content attribute, the outerHTML looks like this:
<div onmouseover="this.style.color='red'" style="border: 1px dotted red;">
I'm the div
</div>
See your updated fiddle.
Long story short, there are two ways to code a handler:
var setColor = function(e) { e.target.style.color = "red"; }
div.onmouseover = setColor; // IDL, not seen by outerHTML
div.setAttribute("onmouseover","setColor(event)"); // content, seen by outerHTML
If you want to retrieve the IDL events somehow, nice proposed eventListenerList
property was removed from DOM3 spec proposal (see here).
If you want to write a firefox addon (something like code inspector), extending the Element.prototype will do the trick (as I tested, it works in Firefox, Chrome and Opera, it doesn't work in IE7):
(function() {
Element.prototype.eventListenerList = {};
Element.prototype._addEventListener = Element.prototype.addEventListener;
Element.prototype.addEventListener = function(a,b,c) {
this._addEventListener(a,b,c);
if(!this.eventListenerList[a]) this.eventListenerList[a] = [];
this.eventListenerList[a].push(b);
};
})();
To be precise, you should also override the Element.prototype.removeEventListener
to remove the event from the custom EventListenerList.
Now you can add the events by addEventListener
as usual:
function handlerA() { alert('a'); }
function handlerB() { alert('b'); }
function handlerC() { alert('c'); }
// attach handlers
div.onclick = handlerC;
div.addEventListener("click",handlerA);
div.addEventListener("click",handlerB);
...and to display the code of the listeners. I will do this for onclick
event, in your code you should iterate through every possible event. Don't forget the eventual onclick
listener (you can't override Element.prototype.onclick
because it is non-configurable property):
var clickListeners = "";
if(div.eventListenerList.click)
div.eventListenerList.click.forEach(function(f) {
clickListeners+= f.toString();
});
if(div.onclick) clickListeners+= div.onclick.toString();
alert(clickListeners);
See and test the fiddle. Put these pieces together as it suits to your addon.
Upvotes: 2
Reputation: 1745
Well, you could wrap the creation of your div
element with a function and then parse and print contents of that function.
Following is a working example (tested in Chrome, Firefox and Safari):
Also here http://jsfiddle.net/smnh/x2zJs/2/
function createDiv() {
var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover = function() {div.style.color = "red"};
div.innerHTML = "I'm the div";
div.creationString = getFunctionContnet(createDiv); // noprint
return div; // noprint
}
function getFunctionContnet(func) {
var regExp = /function[^(]*\([^)]*\)[^{]*{(?:\s*\n)?(\s*)([\s\S]*)(?:\n\s*)}/,
match,
indention, indentionRE,
noprintRE = /\/\/.*noprint.*/,
content = null,
lines, i;
match = regExp.exec(func.toString());
if (match !== null) {
indention = match[1];
content = match[2];
lines = content.split("\n");
// if first line of the function is indented,
// remove that indention from all function lines.
if (typeof indention !== "undefined") {
indentionRE = new RegExp("^" + indention);
for (i = 0; i < lines.length; i++) {
if (indentionRE.test(lines[i])) {
lines[i] = lines[i].substr(indention.length);
}
}
}
// don't print lines with "// noprint"
for (i = lines.length - 1; i >= 0; i--) {
if (noprintRE.test(lines[i])) {
lines.splice(i, 1);
}
}
content = lines.join("\n");
}
return content;
}
Here if you create your div
and log the creationString
you will get the text of the function.
div = createDiv();
console.log(div.creationString);
Upvotes: 0
Reputation: 336
There is nothing built-in that will give you what you want, try the "aardvark bookmarklet" it has a somewhat nice js generating command. http://karmatics.com/aardvark/bookmarklet.html
Upvotes: 0