![](/img/trans.png)
[英]Javascript - Append HTML to container element without innerHTML
[英]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&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&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
數據結構並獲取所需的包裝標簽並采取相應的措施:
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.