2010-08-31 46 views
7

我有這樣的代碼(運行的jQuery 1.4.2)JQuery的:插入到新創建的元素

var elementToAdd = $('<h3>').html('header'); 
var p = $('<p>').html('hello world'); 
elementToAdd.after(p); 
$('div#content').append(elementToAdd); 

然而,輸出

<div id="content"> 
    <h3>header</h3> 
</div> 

該段未添加的 「Hello world」。

我在做什麼錯?


我一直在嘗試了一些變化:

這不起作用或者:

var elementToAdd = $('<div>Header</div>'); 
var p = $('<p>hello world</p>'); 
elementToAdd.after(p); 

或本:

var elementToAdd = $('<h3>header</h3>').after('<p>hello world</p>'); 

但這個工程(在Firefox,在最少):

var elementToAdd = $('<div>').after('<h3>header</h3>').after('<p>hello world</p>'); 

爲什麼?

+1

,它沒有任何意義,()之後是什麼? elementToAdd需要存在才能對其有效的定義 – 2010-08-31 12:22:21

+0

我在閱讀jQuery 1.4.2後允許在斷開連接的DOM節點之後進行鏈接。 – Extrakun 2010-08-31 12:26:48

+0

你能指出一個你讀過的鏈接嗎? – 2010-08-31 12:45:06

回答

3

編輯:修改原來的設置,你可以將.push()一個DOM元素(不是一個jQuery對象)放入集合中。

var elementToAdd = $('<h3>').html('header'); 
var p = $('<p>').html('hello world'); 

    // Push the DOM element in 
elementToAdd.push(p[0]); // [0] gets the DOM element at index 0 
$('div#container').append(elementToAdd);​ 

代替.after(),使用jQuery的.add()方法。

var elementToAdd = $('<h3>').html('header'); 
var p = $('<p>').html('hello world'); 

// Add the new object ----------------v 
$('div#container').append(elementToAdd.add(p));​ 

這會將它追加爲你想要的兄弟姐妹。

它返回一個新的jQuery對象,其中包含兩個元素作爲同輩。因爲它不會修改原始對象,所以您需要在.append()中調用它或將結果存儲在要附加的變量中。


編輯:(正如另一個答案指出,現在可以使用after()add(),在它返回一組新的,不修改原始。)

要解釋爲什麼呢,這是因爲一個jQuery對象是一個DOM元素的數組。 DOM元素可以是具有嵌套後代的單個元素,但不能是兩個兄弟。因此,當您執行.after()時,您正嘗試向陣列中的每個單個元素添加一個同級元素到

爲了處理兄弟姐妹,jQuery將它們作爲附加項存儲在其數組中。

所以,當你通過傳遞兩個或更多的兄弟元素來創建一個jQuery對象時,它將它們分開,並使它們在數組中分開。

var $obj = $("<div>div element</div> <span>span element</span>"); 

這將爲您提供一個jQuery對象,其中包含2個項目的數組。

$obj[0] is the <div> element 
$obj[1] is the <span> element 

所以,如果你是單獨創建它們,你需要使用.add()新項目添加到陣列。

var $obj = $("<div>div element</div>"); 

$obj[0] is the <div> 

var $span = $("<span>span element</span>"); 
$obj = $obj.add($span); 

$obj[0] is the <div> 
$obj[1] is the <span> 
+0

使用add()工程雖然讀了API,但它給我的印象是它比DOM插入方法更昂貴。我對嗎? – Extrakun 2010-08-31 13:21:04

+0

@Extrakun - 刪除以前的評論。它看起來像'.after'現在能夠以類似於'.add()'的方式表現,因爲它返回一個包含這兩個元素的新對象,因此您需要用新的元素覆蓋舊的'elementToAdd'值: 'elementToAdd = elementToAdd.after(p);' – user113716 2010-08-31 13:41:57

+0

我想這會引發使用after()和add()的問題。 insert()被列爲DOM插入,而add()被遍歷。我想這應該是另一個問題,但:D – Extrakun 2010-08-31 13:46:16

6

我不認爲.after作品有沒有被添加到DOM元素還...

試試這個

var elementToAdd = $('<h3>').html('header'); 
var p = $('<p>').html('hello world'); 
$('div#content').append(elementToAdd); 
elementToAdd.after(p); 

編輯:是的,這工作好了! http://jsfiddle.net/tu2GY/

編輯2:好吧,我在此不是非常好,但在這裏不用...

由於@Extrakun指出,jQuery的文檔確實指出,該元素可能無法連接到DOM ...

對於jQuery 1.4,.before().after()也將斷開連接的DOM節點工作。

所以,我深吸了一口氣,打開jQuery的1.4.2.js(在vim:d)以及我發現的是,無論是被傳遞到.after沒有parentNode一個元素,正在用作選擇器字符串我認爲在傳遞jQuery對象時失敗。我會嘗試後我的意思在一分鐘內 或兩個 這裏的一些代碼...(內pushStack法)

ret.selector = this.selector + "." + name + "(" + selector + ")"; 

selector這裏是結束是不管你傳遞給.after。那之後並沒有真正發揮出色。

+0

感謝您冒用源代碼! :) – Extrakun 2010-08-31 13:21:25

+0

哈!它幫助我把jQuery看作*不是一個黑盒子*;) – 2010-08-31 13:30:37

0

'elementToAdd'不是指向元素的jQuery對象。試試這個:

var elementToAdd = $('<h3>'); 
elementToAdd.html('header'); 
var p = $('<p>').html('hello world'); 
$('div#content').append(elementToAdd); 
elementToAdd.after(p); 
+1

不。它是一個指向元素的jquery對象。 **編輯:**這就是爲什麼鏈接工程:) – 2010-08-31 12:21:24

+0

var x = $('a#someID')。attr('href'); //這將返回href內的值,x不會指向元素。或者我錯過了什麼? – 2010-08-31 12:31:11

+1

這就是'.attr'的行爲。但'.html'允許鏈接,因此返回jQuery對象。事實上,如果你用兩個參數調用'.attr',你會得到一個jQuery對象,因此鏈接仍然有效...... – 2010-08-31 12:41:31

0

操縱DOM是一個昂貴的操作,並盡最大努力去做的最低次數,你上面的代碼可以很容易地改變,

$('div#content').append('<h3>header</h3><p>hello world</p>'); 
+0

這只是一個例子。真正的代碼涉及動態地寫出從數據庫中獲取的字符串,並設置一個帶有函數回調的鏈接... – Extrakun 2010-08-31 12:28:00

+0

您還可以使用串聯來創建單個字符串,然後將它傳遞給追加函數 – 2010-08-31 12:53:08

3

有趣。添加一個臨時工程:

var e = $('<h3>').html('header'); 
var p = $('<p>').html('hello world'); 
var result = e.after(p); 
$('div#content').append(result); 

...所以我猜e.after(p)回報 「E後P」,但實際更改即所以它在一個鏈中工作,並且它的工作是斷開的,但不會像你期望的那樣工作。

+0

+1 weee!這解釋了我在jQuery源代碼中看到的內容,'pushStack'方法創建一個新對象並返回它,它代表這兩個元素。 – 2010-08-31 13:39:56

+0

看起來你是對的。如果沒有父節點,它現在將對象推入,返回一個新的集合。 http://github.com/jquery/jquery/blob/master/src/manipulation.js#L146 – user113716 2010-08-31 13:45:45

0

問題是,插入斷開的DOM節點與.before和.after只適用於jQuery 1.4(和衍生物)。

<script src="jquery-1.4.js"></script> 
<script> 
    $('<div/>').after('<p>Test</p>').filter('p').appendTo('body'); 
</script> 
0

對於所有最近的jQuery的版本,你也可以使用將追加用於插入DOM節點的對象:

<script> 
    $("<span/>", { 
    class: "test", 
    html: "<p><b>Click me!</b></p>" 
    }).appendTo("body"); 
</script>