簡體   English   中英

我可以使用innerHTML將所有可能的HTML元素附加到哪個HTML元素?

[英]To what HTML element can I append all possible HTML elements using innerHTML?

我必須將HTML作為字符串傳遞(因為我正在使用postmessage進行通信)。 要將修改應用於html,我正在做:

function foo(my_string) {
  var temp, element_list;

  temp = document.createElement("div")
  temp.innerHTML = my_string;
  element_list = temp.querySelectorAll(".foo");
  ...

我的問題是my_string可以是任何東西,以防我傳遞帶有表行和像這樣的單元格的字符串:

  '<tr>' +
    '<td>' +
      '<a href="#gadget._key=project_module%2F1&amp;gadget.view=view">' +
        'My Test Project 2014/12/16 14:24:48.930904 GMT' +
      '</a>' +
    '</td>' +
    '...' +
  '</tr>'

將其附加到<div>會刪除表中的行和單元格,而我只剩下鏈接。 像這樣:

      '<a href="#gadget._key=project_module%2F1&amp;gadget.view=view">' +
        'My Test Project 2014/12/16 14:24:48.930904 GMT' +
      '</a>' +

題:
是否有一個通用元素,該元素可以接受任何類型的子元素,並且不會修改通過innerHTML傳遞的任何內容?

謝謝!

編輯
該方法用於翻譯html代碼段。 當我更新表時,它將只傳遞生成的表行,而不是在初始頁面呈現時接收整個表。

沒有這樣的元素。 <tr>是一個很好的例子。 根據W3C標准, <tr>的“允許的父元素”是“ A <table><thead><tbody><tfoot>元素。

如果必須按原樣輸入這些字符串,則最好的選擇是對要插入的元素類型進行某種檢測,並在需要時將它們包裝在適當的HTML中。

例如:( 以CodePen的形式查看

HTML

<div id="container"></div>

JavaScript的

var anyone = "<div>In a Div</div>";
var tableOnly = "<tr><td>In a..</td></tr>" +
    "<tr><td>...table</td></tr>";

$(function () {
  var $container = $("#container");
  appendContent(anyone);
  appendContent(tableOnly);

  function appendContent(html) {
    var $html = $(html),
        $parent = $(),
        lastParent = "";
    $html.each(function () {
      var parent = parentTag(this.tagName);

      if(parent !== lastParent)
      {
        $container.append($parent);
        $parent = $(parent);
      }
      $parent.append(this);
      lastParent = parent;
    });

    $container.append($parent);
  }

  function parentTag(tagName) {
    switch (tagName.toLowerCase()) {
      case "tr":
        return "<table></table>";
      default:
        return "<div></div>";
    }
  }

});

編輯:請注意,如果HTML包含的內容不能屬於同一父級,則此處用於檢測HTML中使用的標簽的技術可能會出現問題。 例如,以下代碼將失敗:

appendContent("<tr><td>Also in a table</td></tr><div>Also in a div</div>");

這是因為jQuery如何在內部構建其選擇器。 由於您不能將div標簽作為tr的兄弟,因此div元素將被有效刪除。 這是一個CodePen演示的 ,但是從實際情況來看,這對於OP的需求而言不是問題。 如果是這樣,則可以使用其他檢測標記的方法,例如正則表達式。

如果您使用缺少的標簽附加格式錯誤的HTML數據(如您所注意到的),那么您將受到瀏覽器DOM分析器的憐憫,將每一個都刪除,直到返回符合標准的HTML。

如果您的主要關注點( 項目方面 )僅涉及表HTML內容 ,則可以將字符串視為XML數據結構並獲取所需的包裝標簽並采取相應的措施:

jsBin演示

function sanitizeHTML( string ) {

  // Treat friendly a HTMLString as XML structure:
  var par = new DOMParser();
  var doc = par.parseFromString(string, 'text/xml');
  var chd = doc.firstChild;
  var tag = chd.nodeName.toUpperCase(); // Get the tag
  var ele;

  function wrapWith(parent, childEl){ // Wrap a node into a parent
    var p = document.createElement(parent);
    p.appendChild(childEl);
    return p;                         // And return that parent element.
  }

  if(/^(THEAD|TBODY|TR)$/.test(tag)){ // If THEAD or TBODY or TR
    ele = wrapWith("table", chd);     // just wrap in TABLE.
  }else if(/^(TD|TH)$/.test(tag)){    // Else if TD or TH
    ele = wrapWith("tr", chd);        // wrap first in TR
    ele = wrapWith("table", ele);     // and than in TABLE.
  }else{
    // All fine. Do we need something here?
  }

  return ele || chd; // Returns a HTMLElement
}

// This will return the final HTMLElement:
// var myEl = sanitizeHTML( str ); 

// Let's see in console:
console.log( sanitizeHTML( str ).outerHTML ); 

為了簡單起見,以上代碼將考慮僅包含一個子代的字符串。
要擴展它-循環doc對象的所有子對象。

看到這個jsfiddle: http : //jsfiddle.net/Grezzo/x1qxjx5y/

<table>使用<tr>可以。

這是因為您將<tr>放在<div>中是無效的。

像這樣在頁面中放置未經消毒的內容是真正的安全風險

更新:我更新了jsfiddle,使其包含兩個未被javascript修改的<div> ,並且您可以看到,如果<tr>不在<table>父級中,則它們會被剝離: http : //jsfiddle.net/ Grezzo / x1qxjx5y / 1 /

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM