如何获取现有HTML元素的JS代码?

时间:2014-03-27 16:31:27

标签: javascript dom firefox-addon

我想知道是否有任何方法可以使用任何现有方法获取现有HTML元素的JS代码。我正在尝试打印任何DOM元素的代码生成器,因此当用户单击该网页的任何HTML元素时,将显示一条消息,其中包含用于在Javascript中创建该元素的源代码。

例如,我创建了一个Div:

var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover=function(){div.style.color = "red"};
div.innerHTML = "I'm the div";

然后我试图获取源代码,但是:

document.body.appendChild(div.innerHTML);

此选项仅写入文字内容:"我是div"。所以我尝试了:

document.body.appendChild(div.outerHTML);

但它写的HTML代码没有onmouseover功能:"我是div"

我真正需要的是显示此代码(或类似的代码):

var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover=function(){div.style.color = "red"};
div.innerHTML = "I'm the div";

http://jsfiddle.net/x2zJs/

你知道我在哪里可以开始阅读吗? 非常感谢,

4 个答案:

答案 0 :(得分:2)

outerHTML

outerHTML是一个很好的选择,有几个限制:

  1. 今天(2014年)you can't get attached listeners natively
  2. outerHTML使用html node serialization,其中使用了xml attributes serialization algorithm
  3. 换句话说,忽略IDL属性,只序列化内容属性。

    IDL属性的事件编码为

    div.onmouseover=function(){div.style.color = "red"};
    div.addEventListener("mouseover",function() {div.style.backgroundColor="blue";});
    

    详细了解events

    内容属性的事件编码为

    div.setAttribute("onmouseover","this.style.color='red'");
    

    使用content属性,outerHTML如下所示:

    <div onmouseover="this.style.color='red'" style="border: 1px dotted red;">
      I'm the div
    </div>
    

    请参阅your updated fiddle

    长话短说,有两种方法可以编写处理程序:

    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
    

    EventListenerList对象

    如果你想以某种方式检索IDL事件,那么从DOM3规范提案中删除了很好的建议eventListenerList属性(参见here)。

    如果你想编写一个firefox插件(比如代码检查器),扩展Element.prototype就可以了(我测试过,它适用于Firefox,Chrome和Opera,它在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);
      };
    })();
    

    准确地说,您还应该覆盖Element.prototype.removeEventListener以从自定义EventListenerList中删除事件。

    现在您可以像往常一样按addEventListener添加事件:

    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);
    

    ...并显示监听器的代码。我会为onclick事件执行此操作,在您的代码中,您应该遍历每个可能的事件。不要忘记最终的onclick侦听器(您无法覆盖Element.prototype.onclick,因为它是不可配置的属性):

    var clickListeners = "";
    if(div.eventListenerList.click)
    div.eventListenerList.click.forEach(function(f) {
      clickListeners+= f.toString();
    });
    if(div.onclick) clickListeners+= div.onclick.toString();
    alert(clickListeners);
    

    查看并测试the fiddle。把这些碎片放在一起,因为它适合你的插件。

答案 1 :(得分:0)

没有任何内置可以提供你想要的东西,试试“aardvark bookmarklet”它有一个不错的js生成命令。 http://karmatics.com/aardvark/bookmarklet.html

答案 2 :(得分:0)

好吧,你可以用函数包装你的div元素的创建,然后解析并打印该函数的内容。

以下是一个工作示例(在Chrome,Firefox和Safari中测试):
同样在这里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;
}

如果您创建div并记录creationString,则会获得该功能的文字。

div = createDiv();
console.log(div.creationString);

enter image description here

答案 3 :(得分:0)

如果您可以控制元素的创建,则可以确保每个元素都在其自己的独立函数中创建。然后一个简单的函数可以得到函数体。

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("}"));
}

这是一个有效的例子。 http://jsfiddle.net/C5b7n/