我试图在我创建的iFrame上设置data()
。
这就是我正在做的:
// 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和它的body标签时,attr("foo")
是正确设置的,我也可以像这样控制它:
console.log(newElement.contents().find("body").attr("foo"));
但是当我尝试使用data()
或data("config")
来控制config
时,如下所示:
console.log(newElement.contents().find("body").data("config"));
它总是返回undefined
:
为什么不可能在iFrame上设置jQuery data()
?还是我做错了什么?
谢谢你的帮助!
jQuery不将数据存储在元素本身,而是存储在jQuery.cache
中。
在jQuery代码中有这部分:
jQuery.expando: "jQuery" + ( core_version + Math.random() ).replace( /D/g, "" )
正如你所看到的,每个jQuery加载都会创建一个唯一的扩展。
expando被用作属性来存储DOM元素的标识符。
使用.data(key,value)
在元素中存储数据时,jQuery执行以下步骤:
- 检查
element[jQuery.expando]
中的元素是否有id
,如果没有,则创建一个唯一的id
。 - 检查是否有
jQuery.cache[id]
条目,如果没有,创建一个空对象用于存储元素的数据。
如果你调用.data(key,value)
数据存储在窗口中你使用的jQuery实例定义在。
如果你有一个jQuery对象在parent
和一个在iframe
,这些有两个不同的expandos
,因为随机数。如果在iframe的元素上从父类jQuery对象调用.data()
,则使用父类的expando
,并且数据存储在父类中。如果你使用iframe的jQuery,然后在相同的元素上调用.data
,那么iframe的jQuery将找不到任何数据,因为它一方面有不同的expando
,另一方面数据存储在父窗口。
所以如果你想在iframe中设置数据,你应该使用iframe的jQuery对象。$('iframe')[0].contentWindow.jQuery("body").data( ... )
设置数据,然后可以再次从iframe内部检索数据,因为这样您就可以使用相同的jQuery对象来设置和读取数据。
编辑还有一点很重要。因为数据存储在使用的jQuery实例中,所以不应该使用jQuery在另一个上下文中存储数据。JQuery有一个清理方法,当你用JQuery删除元素时调用它来删除事件监听器和从jQuery.cache
中删除数据。但是如果你使用jQuery为另一个上下文中的元素存储数据,这个清理方法将失败(例如,如果你在iframe中加载另一个页面)。因此,只有当你重新加载父元素时,数据才会被释放。
通过向$(selector, scope)
提供第二个参数,确保您的jQuery选择器在相关范围内查找。
$(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