2009-10-29 114 views
15
var oFra = document.createDocumentFragment(); 
// oFra.[add elements]; 
document.createElement("div").id="myId"; 
oFra.getElementById("myId"); //not in FF 

如何在将碎片附加到文档之前获取“myId”?有什么方法可以在documentFragment中查找元素吗?

+3

这个问题在2009年提出。__ 2012年,我们有querySelectorAll,它处理文档片段___。请参阅下面的@ Stephen的答案。 – mikemaccana 2012-05-27 18:19:00

回答

0

什么:

var oFra = document.createDocumentFragment(); 
var myDiv = document.createElement("div"); 
myDiv.id="myId"; 
oFra.appendChild(myDiv); 
oFra.getElementById("myId"); //not in FF 

除非你已经添加了创建div到您的文档片段,我不知道为什么getElementById会找到它?

--edit

如果你愿意推出自己的getElementById功能,那么你应该能够得到你后的参考,因为此代码的工作:

var oFra = document.createDocumentFragment(); 
var myDiv = document.createElement("div"); 
myDiv.id = "myId"; 
oFra.appendChild(myDiv); 
if (oFra.hasChildNodes()) { 
    var i=0; 
    var myEl; 
    var children = oFra.childNodes; 
    for (var i = 0; i < children.length; i++) { 
     if (children[i].id == "myId") { 
      myEl = children[i]; 
     } 
    } 
} 
window.alert(myEl.id); 
+0

我试图避免这种解决方案,因为我在片段中设计了一个数据条目表单,添加了事件并附加到文档中。适用于IE。 原因似乎是在IE中片段从文档中继承,但是在FF继承自Node(W3C) – pkario 2009-10-29 12:34:53

+0

好,但是如果你用JS构建表单,为什么不在创建它们时继续引用元素并使用那些引用来添加事件? – robertc 2009-10-29 12:49:30

+0

每种形式都有很多按钮,文本框,组合等。 我尝试坚持ID并尽量减少dom对象引用。 我会先附加并分配事件。 – pkario 2009-10-29 12:54:15

7

DocumentFragment API至少可以说:它没有定义任何属性或方法,这意味着它只支持在Node API中定义的属性和方法。由于getElementById等方法在Document API中定义,因此它们不能与DocumentFragment一起使用。

+0

即使getElementById在Document API中定义,它也不会在未附加到dom的新创建的元素上工作。 myObj.getElementById不起作用,而myObj.getElementsByTagName起作用。 – Olivvv 2009-12-07 09:55:21

+2

@Oiviv:这是可以预料的:'getElementById'是'HTMLDocument'的一种方法http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-36113835 ,而'getElementsByTagName'是'Document' http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#i-Document和'Element'的一种方法http: //www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-745549614因此,当尝试在对象上调用它时,'getElementById'将始终引发异常元素类型是否连接到DOM。 – NickFitz 2009-12-07 16:49:53

0

一个外部源,下面列出,显示出下面的代码片断:

var textblock=document.createElement("p") 
textblock.setAttribute("id", "george") 
textblock.setAttribute("align", "center") 

哪个显示设定对象的ID参数的不同方式。

Javascript Kit - Document Object Methods

7

NickFitz是正确的,DocumentFragment没有你DocumentElement预计API,在标准或浏览器中(这是一种耻辱,这将是非常方便的,能够设置片段的innerHTML

即使框架在这里也没有帮助,因为它们往往需要Nodes在文档中,或者使用上下文节点上不存在的片段上的方法,您可能必须编写您自己的,例如:

function Node_getElementById(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= Node_getElementById(child, id); 
      if (child!==null) 
       return child; 
     } 
     return null; 
} 

跟踪参考文件几乎肯定会更好,而不是像上面那样依赖于一个天真,性能不佳的函数。

var frag= document.createDocumentFragment(); 
var mydiv= document.createElement("div"); 
mydiv.id= 'myId'; 
frag.appendChild(mydiv); 
// keep reference to mydiv 
24

所有这些答案都比较老了,从回来的时候querySelectorAllquerySelector尚未得到广泛应用。应该注意的是,接受CSS选择器作为参数的这两个函数在现代浏览器中可以工作于DocumentFragment,并且应该是处理问题情况的首选方式。在某些答案中提供的备用解决方案对于不支持querySelectorAllquerySelector的传统浏览器来说是一个好方法。

下面是一个例子用法:

var df = document.createDocumentFragment(); 
var div = document.createElement('div'); 
div.id = 'foo'; 
df.appendChild(div); 
var result = df.querySelector('#foo'); // result contains the div element 

一个良好的实现都应该先使用对象检测,看看浏览器是否支持这一点。例如:

function getElementByIdInFragment(fragment, id) { 
    if (fragment.querySelector) { 
     return fragment.querySelector('#' + id); 
    } else { 
     // your custom implementation here 
    } 
} 
+0

我确信有另外一种方法,比从documentfragment获取元素。无论如何**你将失去所有的好处**。 – 2014-03-02 09:55:45

1

使用jQuery:

// Create DocumentFragment 
var fragment = document.createDocumentFragment(), 
    container = document.createElement('div'); 

container.textContent = 'A div full of text!'; 
container.setAttribute('id', 'my-div-1'); 
container.setAttribute('class', 'a-div-class'); 
fragment.appendChild(container); 

// Query container's class when given ID 
var div = $('<div></div>').html(fragment); 
console.log(div.find('#my-div-1').attr('class')); 

的jsfiddle:http://jsfiddle.net/CCkFs/

你必须创建使用jQuery的div的开销,虽然。有点哈克,但它的作品。

+0

$(“

”).find(#my-div-1“)起作用。您只是无法搜索根节点。 – Scott 2014-01-08 15:45:21

0

我的DOM在元素标记下有一个#文档片段

这是我在用的(使用jQuery),我也有,我有一个字符串的HTML DOM的使用情况 -

var texttemplate = $(filecontents).find('template').html(); 


$(texttemplate).children() 

     <p>​Super produced One​</p>​, 
     <appler-one>​</appler-one>, 
     <p>​Super produced Two​</p>, 
     <appler-two>​…​</appler-two>] 

$(texttemplate).html() 

       "<p>Super produced One</p> 
       <appler-one></appler-one> 
       <p>Super produced Two</p> 
       <appler-two> 
        <p>Super produced Three</p> 
        <appler-three></appler-three> 
       </appler-two>" 


$(texttemplate).find("appler-one") 

       [<appler-one>​</appler-one>​] 
0

最好的迄今为止的方式来找出你可以和不能用DocumentFragment做的是检查它的原型:

const newFrag = document.createDocumentFragment(); 
const protNewFrag = Object.getPrototypeOf(newFrag); 
console.log('£ protNewFrag:'); 
console.log(protNewFrag); 

我得到

DocumentFragmentPrototype {的getElementById:的getElementById(), querySelector器:querySelector(),querySelectorAll:querySelectorAll()和 前置:前置(),追加:追加(),儿童:吸气剂, firstElementChild:吸气剂,lastElementChild:吸气剂, childElementCount:吸气剂,1更...}

...它告诉我,我可以做这样的事情:

const firstChild = newFrag.children[ 0 ]; 

PS这是行不通的:

const firstChild = Object.getPrototypeOf(newFrag).children[ 0 ]; 

...你会被告知“对象没有实现DocumentFragment接口”

相关问题