2013-05-22 38 views
0

我被困在試圖在我創建的iFrame上設置data()如何在iFrame body標籤上設置jQuery數據()並從iFrame中檢索它?

這是我在做什麼:

// options > my configuration object 
    // options.src = eg "path/foo.html" 
    // options.id = uuid 
    // options.parent = $(elem) 
    // options.param = JSON object 

    newHTML = document.createElement("iframe"); 
    newHTML.setAttribute("src", options.src); 
    newHTML.setAttribute("frameborder", 0); 
    newHTML.setAttribute("seamless", "seamless"); 
    newHTML.setAttribute("data-id", options.id); 

    newParentElement = options.parent.parent()[0]; 
    options.parent.replaceWith(newHTML); 

    // select 
    newRootElement = newParentElement.querySelectorAll(
    '[data-id="'+options.id+'"]' 
); 

    // add configuration 
    $(newRootElement[0]).load(function() { 
    var newElement = $(this); 
    if (options.param) { 
     newElement.contents().find("body").attr("foo","bar").data("config", options.param); 
    } 
    }); 

當我看着我的iframe和它的機身標籤,該attr("foo")設置正確,我也安慰它,如下所示:

console.log(newElement.contents().find("body").attr("foo")); 

但是當我嘗試使用任何data()data("config")勸慰config,像這樣:

console.log(newElement.contents().find("body").data("config")); 

它總是返回undefined

問題
爲什麼不能設置一個jQuery data()的iframe?或者我做錯了什麼?

感謝您的幫助!

+0

是options.param一個有效的字符串?爲什麼你不使用jQuery語法來處理你的所有腳本?會更容易:) – Alex

+0

jQuery不會將數據與元素本身一起存儲。它只是用元素存儲一個'id'。數據本身存儲在'jQuery.cache'中。如果您使用父對象的「jQuery」對象設置iframe外部的數據,則會在父對象中設置_lives_並且無法使用帶iframe的jQuery對象的.data來檢索數據。那是因爲兩個jQuery對象不共享他們的'.cache'對象。 –

+0

@ t.niese:啊。謝謝。你能回答一下嗎,我可以檢查嗎? – frequent

回答

2

jQuery的不存儲與元素本身,而是在jQuery.cache數據。

在jQuery代碼你有這樣的一部分:

jQuery.expando: "jQuery" + (core_version + Math.random()).replace(/\D/g, "") 

正如你可以看到每個jQuery的加載創建一個唯一的expando。

expando被用作屬性來存儲DOM元素的標識符。

當你存儲與.data(key,value)數據中的一個元素的jQuery做以下步驟:

  1. 檢查是否有與存儲在element[jQuery.expando]元素的id如果不是它創建了一個獨特的id
  2. 檢查是否有jQuery.cache[id]條目,如果沒有創建一個空對象來存儲元素的數據。

所以,如果你.data(key,value)數據存儲在窗口中使用jQuery的實例中被定義。

如果你有在iframeparent和一個jQuery對象這有兩個不同的expandos由於隨機數。如果您從iframe的元素上的父級jQuery對象調用.data(),則會使用父級的expando,並將數據存儲在父級中。如果再使用I幀的jQuery,然後調用.data在相同的元素作爲iframe的jQuery的之前不會發現任何數據,因爲它一方面是一個不同的expando並在另一方面,數據存儲在父窗口。

所以,如果你想在你應該使用不同iframe jQuery對象的iframe來設置數據。 $('iframe')[0].contentWindow.jQuery("body").data(...)設置數據,則有可能再次從iframe中retrive的數據,因爲這樣你使用相同的jQuery對象設置和讀取數據。

編輯 一個額外的和重要的說明。由於數據與使用的jQuery實例一起存儲,因此不應該使用jQuery將數據存儲在另一個上下文中。 JQuery有一個清理方法,當您使用jQuery刪除元素時會調用這個元素,這會刪除事件偵聽器並從jQuery.cache中刪除數據。但是,如果您使用jQuery爲另一個上下文中的元素存儲數據,則此清除方法將失敗(例如,如果您在iframe中加載另一個頁面)。因此,如果您重新加載父項,數據將僅被釋放。

+0

很好的解釋。謝謝! – frequent

+0

@frequent可能是我回答這個問題也會對您有用:使用Javascript:可以將數據通過iframe通過雙向?](http://stackoverflow.com/questions/15884994/javascript-can-data-be -passed-bi-directionalally-through-an-iframe /) –

+0

很酷。一旦我有iframes工作,我會做這樣的事情:-)再次感謝! – frequent

2

確保您的jQuery選擇器正在通過提供第二個參數$(selector, scope)在相關範圍內查找。

$(function() { 
    var scope = $('iframe')[0].contentWindow.document; // <iframe> 
    $('body', scope).data('id', 'some id');   // set data on body of iframe 
    console.log($('body', scope).data('id'));   // ==> 'some id' 
}); 

這裏就是我成功設置數據iframe的身體,然後檢索小提琴:http://jsbin.com/ecenij/1/edit

+0

很酷。 '範圍'是方便的。嘗試以上,以及它是否可能是時機問題。 – frequent

+0

@Vadim你不應該設置數據或附加的事件偵聽器這種方式,因爲這時如果加載其他頁面中的iframe(那麼設置與數據的jQuery的清理方法將失敗'.data'在iframe會在內存中,直到父窗口重新加載。) –

相關問題