2015-04-23 63 views
1

我有以下代码,它将HTML标记简单地解析为DOM对象。使用id检索嵌套在另一个元素中的元素

var html_str = '<div id="body-wrapper">\ 
     <div id="container-1">\ 
      <p>This is the first container - Line 1</p>\ 
      <p>This is the first container - Line 2</p>\ 
      <p><img src="assets/img/pull_1.jpg"></p>\ 
     </div>\ 
     <div id="container-2">\ 
      <p>This is the second container - Line 1</p>\ 
      <p>This is the second container - Line 2</p>\ 
      <p>This is the second container - Line 3</p>\ 
      <p><img src="assets/img/pull_2.jpg"></p>\ 
     </div>\ 
     <div id="container-3">\ 
      <p>Test</p>\ 
      <p><img src="assets/img/pull_3.jpg"></p>\ 
     </div>\ 
    </div>'; 

var elem_obj = document.createElement("div"); 
elem_obj.innerHTML = html_str; 

如何从elem_obj内获得与id == container-1元素?只有香草JavaScript和elem_obj.querySelector('#container-1')以外的东西,因为我需要支持低于版本8的IE。

谢谢。

+0

你是如何得到这些多JS字符串工作? – Xufox

+0

创建一个'DocumentFragment'。然后你可以使用'docFrag.getElementById'。 http://stackoverflow.com/questions/1643349/is-there-any-way-to-find-an-element-in-a-documentfragment – Amadan

+0

@Xufox:Doh。太多的jQuery,我几乎从来没有使用纯DOM再多...谢谢,修复。 – Amadan

回答

1

正如我在评论中所说的,对激烈争论不完整的数据表示歉意。虽然这是真的旧的IE可以在DocumentFragment中使用getElementById,但对于较新的浏览器通常不是这样,所以需要采用混合策略以实现最佳兼容性。

var html = '<div id="body-wrapper">\ 
 
    <div id="container-1">\ 
 
    <p>This is the first container - Line 1</p>\ 
 
    <p>This is the first container - Line 2</p>\ 
 
    <p><img src="#"></p>\ 
 
    </div>\ 
 
    <div id="container-2">\ 
 
    <p>This is the second container - Line 1</p>\ 
 
    <p>This is the second container - Line 2</p>\ 
 
    <p>This is the second container - Line 3</p>\ 
 
    <p><img src="#"></p>\ 
 
    </div>\ 
 
    <div id="container-3">\ 
 
    <p>Test</p>\ 
 
    <p><img src="#"></p>\ 
 
    </div>\ 
 
</div>'; 
 

 

 
// from http://stackoverflow.com/a/1643512/240443 
 
function getElementByIdFromNode(node, id) { 
 
    for (var i = 0; i < node.childNodes.length; i++) { 
 
    var child = node.childNodes[i]; 
 
    if (child.nodeType !== 1) // ELEMENT_NODE 
 
     continue; 
 
    if (child.id === id) 
 
     return child; 
 
    child = getElementByIdFromNode(child, id); 
 
    if (child !== null) 
 
     return child; 
 
    } 
 
    return null; 
 
} 
 
// based on http://stackoverflow.com/a/1643383/240443 
 
function getElementByIdFromString(html, id) { 
 
    var div = document.createElement("div"); 
 
    div.innerHTML = html; 
 
    // New browsers 
 
    if (div.querySelector) { 
 
    return div.querySelector("#" + id); 
 
    } 
 
    // Old IE 
 
    var frag = document.createDocumentFragment(); 
 
    if (frag.getElementById) { 
 
    frag.appendChild(div); 
 
    return frag.getElementById(id); 
 
    } 
 
    // Anything else just in case 
 
    return getElementByIdFromNode(div, id); 
 
} 
 
var container3 = getElementByIdFromString(html, "container-3"); 
 
console.log(container3);

+0

嗯...你自己呢?! –

+1

代码中的评论清楚地说明了我的来源。 – Amadan

+0

对不起,没有看到。非常感谢您将所有内容融合在一起。它像一个魅力。为了测试,我隔离了每个部分[即querySelector,documentFragment和getElementByIdFromNode],并且它们都可以正常工作,所以这应该可以回溯到IE6。干杯。 –

1

建议的解决方案(替代DocumentFragment):您可以使用循环搜索所需的元素。

JSFiddle(查看控制台输出)。

环路看起来像这样:

var elem_obj_containers = elem_obj.children[0].children; 
    // All <div>s with those “container-” IDs 

var container1_element=null; // The result or null 

for(var i=0;i<=elem_obj_containers.length;i++){ 
    if(elem_obj_containers[i].id=='container-1'){ // Checking for ID 
     container1_element=elem_obj_containers[i]; // Assigning result 
     console.log(elem_obj_containers[i]); // Verify result 
     break; // Show’s over! 
    } 
} 

因此,如果ID被找到时,元件被分配给container1_element,否则变量保持null(像真正document.getElementById)。

MDN’s page for children开始,它应该一直回到IE6。 IE 6,7和8也仅包含children中的HTML注释节点。这不应该是一个大问题。

+1

没有不敬的意图,但...手动JavaScript DFS与'getElementById'的直接C API ...我不会将其称为另一种选择。这只是一个教育练习,我绝对不会在生产中使用它。 (它甚至不是一个合适的DFS,它仅限于在第二级搜索ID,所以它不像'getElementById'那么普遍。) – Amadan

+0

对,这很大程度上取决于嵌套级别。那么,你可以发布关于“DocumentFragment”的答案,或者将这个问题标记为另一个问题的重复(如果是)。 – Xufox

+0

我相信这是重复的。 OP没有,我在使用我的超级大国之前试图说服他。 :p – Amadan