get opening tag including attributes - outerHTML without innerHTML

后端 未结 7 1325
花落未央
花落未央 2020-12-10 03:22

I would like to retrieve a certain tag element with its attributes from the DOM. For example, from


  link text


        
相关标签:
7条回答
  • 2020-12-10 03:24

    Unfortunately, @AaronGillion's answer isn't reliable as I said in my comment. Thank @sus. I recommend his/her way with a little change to support <self-closing tags />:

    function getOpenTag(element: HTMLElement): string {
        const outerHtml = element.outerHTML;
        const len = outerHtml.length;
        
        const openTagLength = outerHtml[len - 2] === '/' ? // Is self-closing tag?
                len :
                len - element.innerHTML.length - (element.tagName.length + 3);
        // As @sus said, (element.tagName.length + 3) is the length of closing tag. It's always `</${tagName}>`. Correct?
        
        return outerHtml.slice(0, openTagLength);
    }
    

    The code is in typescript. Remve types (HTMLElement and number) if you want javascript.

    0 讨论(0)
  • 2020-12-10 03:26

    This can be done without any String manipulation.

    Instead, you can use the element's internals and build the string yourself from there:

    function getTagHTML(el) {
      if (!el instanceof HTMLElement) return null;
      let result = `<${el.tagName.toLowerCase()}`;
      for (const attribute in el.attributes) {
        if (el.attributes[attribute].nodeValue) 
          result += ` ${el.attributes[attribute].name}="${el.attributes[attribute].nodeValue.replace(/"/g, "&quot;")}"`
      }
      result += `></${el.tagName.toLowerCase()}>`;
      return result;
    }
    
    console.log(getTagHTML(document.getElementById('outer')));
    <div id="outer" class='i-want-"this"'>
      <span>I do not want this</span>
    </div>

    Please note that for self-closing elements like <img /> this would give you an unwanted and incorrect closing tag. Feel free to adjust the code accordingly.

    0 讨论(0)
  • 2020-12-10 03:29
    var wrapper = $('.class').clone().attr('id','').empty();
    
    • You might want to change the selector to more exactly match the <a> element you're looking for.
    • clone() creates a new copy of the matched element(s), optionally copying event handlers too.
    • I used attr to clear the element's ID so that we don't duplicate IDs.
    • empty() removes all child nodes (the 'innerHTML').
    0 讨论(0)
  • 2020-12-10 03:29

    For future Googlers, there is a way to do this without jQuery:

    tag = elem.outerHTML.slice(0, elem.outerHTML.indexOf(elem.innerHTML));
    

    Since outerHTML contains the opening tag followed by a mirror of what innerHTML contains, we can substring the outerHTML from 0 (the beginning of the opening tag) to where the innerHTML begins (end of opening tag), and since innerHTML is a mirror of outerHTML, except for the opening tag, only the opening tag will be left!

    This one works with <br> tags, <meta> tags, and other empty tags:

    tag = elem.innerHTML ? elem.outerHTML.slice(0,elem.outerHTML.indexOf(elem.innerHTML)) : elem.outerHTML;
    

    Because innerHTML would be empty in self-closing tags, and indexOf('') always returns 0, the above modification checks for the presence of innerHTML first.

    0 讨论(0)
  • 2020-12-10 03:32

    If someone is not using jQuery . . .

    elem.outerHTML
    "<a href="#" class="class">
      link text
    </a>"
    elem.cloneNode().outerHTML
    "<a href="#" class="class"></a>"
    

    If you want to be safe for Firefox etc. released before mid-2014, use cloneNode(false) to avoid getting inner stuff.

    Reference: https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode

    0 讨论(0)
  • 2020-12-10 03:49

    Here is my solution:

    opentag=elem.outerHTML.slice(0, elem.outerHTML.length-elem.innerHTML.length-elem.tagName.length-3);
    

    I suppose, that close tag is of the form: "</"+elem.tagName+">".

    0 讨论(0)
提交回复
热议问题