代码之家  ›  专栏  ›  技术社区  ›  Nick Chapman

是否有等效于elem.innerHTML的方法来获取标记体中的代码?

  •  1
  • Nick Chapman  · 技术社区  · 10 年前

    如果我有以下内容:

    <p class="demo" id="first_p">
        This is the first paragraph in the page and it says stuff in it.
    </p>
    

    我可以用

    document.getElementById("first_p").innerHTML
    

    得到

    This is the first paragraph in the page and it says stuff in it. 
    

    但有没有简单的方法可以运行,并以字符串形式返回

    class="demo" id="first_p"
    

    我知道我可以遍历元素的所有属性以分别获取每个属性,但是否有一个函数返回 tagHTML 或者类似的东西?

    5 回复  |  直到 10 年前
        1
  •  1
  •   The Spooniest    10 年前

    下面的代码有些生涩:我把它写成了一行,但我在这里把它分成了几行。但是 这将得到一个普通对象,其中键是属性名称,值是相应属性的值 :

    Array.prototype.reduce.call(
        document.getElementById('first_p').attributes,
        function (attributes, currentAttribute) {
            attributes[currentAttribute.name] = currentAttribute.value;
            return attributes;
        },
        {}
    );
    

    经过这一过程, document.getElementById('first_p').attributes 获取元素属性的NamedNodeMap。NamedNodeMap不是数组,而是 Array.prototype.reduce.call(...) 电话 Array.prototype.reduce 在NamedNodeMap上,就像它是一个数组一样。我们可以这样做,因为NamedNodeMap被编写为可以像数组一样访问。

    但我们不能就此止步。我提到的NamedNodeMap是Attr对象的数组,而不是名值对的对象。我们需要转换它,这是其他参数 阵列.原型.减少 发挥作用。

    当它不是以一种奇怪的方式被调用时, 阵列.原型.减少 有两个参数。第二个论点(这是我们的第三个论点,因为我们这样称呼它)是我们想要建立的对象。在我们的案例中,这是一个全新的裸对象: {} 你在最后看到的。

    第一个参数 阵列.原型.减少 (这对我们来说也是第二个)是另一个函数。该函数将为循环中的每个项调用一次,但它需要两个参数。这个 第二 参数是当前循环项,这很容易理解,但第一个参数有点疯狂。这个 第一 当我们调用该函数时,它的第一个参数是我们要构建的对象(即最后一个参数 阵列.原型.减少 此后的每一次,第一个参数都是该函数上次调用时返回的值。 阵列.原型.减少 返回最后一次对其内部函数的调用所返回的内容。

    所以我们从一个空对象开始。然后,对于元素属性中的每个Attr,我们向对象添加一些东西,并返回它。当最后一次调用完成时,对象完成,因此我们返回它。这就是我们制作属性列表的方法。

    如果你想要标签中的确切代码,比如String,那么恐怕没有标准的函数来精确地得到它。 但我们可以得到该代码的近似值 ,具有类似的设置:

    Array.prototype.map.call(
        document.getElementById('first_p').attributes,
        function (currentAttribute) {
            return currentAttribute.name + '=' + JSON.stringify(currentAttribute.value);
        }
    ).join(' ');
    

    基本原理是相同的:我们使用NamedNodeMap并在其上调用Array函数,但这次我们使用 map 而不是 reduce 。你可以想到 地图 作为 减少 :它总是建立一个数组,原始元素中的每个元素都有一个元素。因此,您甚至不需要提及正在构建的对象:回调函数只有一个参数,我们只需返回要放入新Array中的对象。完成后,我们有一个“name=”value“”字符串数组,然后用“”连接。

        2
  •  1
  •   dee-see Tom Ritsema    10 年前

    它不是内置属性,但可以使用类似数组的对象 attributes 来获得你想要的东西。

    Array.prototype.map.call(element.attributes, function (el) {
      return el.name + '="' + el.value + '"';
    }).join(' ')
    

    这是假设浏览器支持 map 作用这个 Array.prototype.map.call 部分原因是 属性 不是真正的数组,也没有 join 方法,但因为它是一个类似JavaScript的动态数组,所以我们可以调用 地图 不管怎么说。

    带有页脚的当前页面示例 div :

    var element = document.getElementById('footer')
    Array.prototype.map.call(element.attributes, function (el) {
      return el.name + '="' + el.value + '"';
    }).join(' ');
    // "id="footer" class="categories""
    
        3
  •  1
  •   Indranil Mondal    10 年前

    您可以尝试以下操作:-

          var attributes = '';
                for(var i=0; i<document.getElementById("first_p").attributes.length; i++){
                    var attr = document.getElementById("first_p").attributes[i];
                    attributes += attr.nodeName+"='"+attr.nodeValue+"' "
                }
                console.log(attributes);
    
        4
  •  0
  •   Jnatalzia    10 年前

    您可以使用 document.getElementById("first_p").attributes 获取该DOM元素上所有属性的数组

    如果您想将它们全部放在一个字符串中,请执行以下操作: document.getElementById("first_p").attributes.join(' ') 以获得所需的输出

        5
  •  0
  •   David Thomas    10 年前

    嗯,虽然目前没有什么可以直接做到这一点(尽管使用 Node 的属性是一种更可靠的方法,一种选择是自己创建此方法:

    HTMLElement.prototype.tagHTML = function(){
        // we create a clone to avoid doing anything to the original:
        var clone = this.cloneNode(),
        // creating a regex, using new RegExp, in order to create it
        // dynamically, and inserting the node's tagName:
            re = new RegExp('<' + this.tagName + '\\s+','i'),
        // 'empty' variables for later:
            closure, str;
    
        // removing all the child-nodes of the clone (we only want the
        // contents of the Node's opening HTML tag, so remove everything else):
        while (clone.firstChild){
            clone.removeChild(clone.firstChild);
        }
    
        // we get the outerHTML of the Node as a string,
        // remove the opening '<' and the tagName and a following space,
        // using the above regular expression:
        str = clone.outerHTML.replace(re,'');
    
        // naively determining whether the element is void
        // (ends with '/>') or not (ends with '>'):
        closure = str.indexOf('/>') > -1 ? '/>' : '>';
    
        // we get the string of HTML from the beginning until the closing
        // string we assumed just now, and then trim any leading/trailing
        // white-space using trim(). And, of course, we return that string:
        return str.substring(0,str.indexOf(closure)).trim();
    };
    
    console.log(document.getElementById('test').tagHTML());
    console.log(document.getElementById('demo').tagHTML());
    

    JS Fiddle demo .