我一直试图在我创建的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及其正文标记时,attr("foo")
已正确设置,我也可以这样设置:
console.log(newElement.contents().find("body").attr("foo"));
但是当我尝试使用config
或data()
来管理data("config")
时,就像这样:
console.log(newElement.contents().find("body").data("config"));
它始终返回undefined
问题:
为什么无法在iFrame上设置jQuery data()
?或者我做错了什么?
感谢您的帮助!
答案 0 :(得分:2)
通过向$(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
答案 1 :(得分:2)
jQuery不会将数据与元素本身一起存储,而是存储在jQuery.cache
。
在jQuery代码中你有这个部分:
jQuery.expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" )
正如您所看到的,每个jQuery加载都会创建一个唯一的expando。
expando用作存储DOM元素的标识符的属性。
当您使用.data(key,value)
将数据存储在元素中时,jQuery会执行以下步骤:
id
中是否存有element[jQuery.expando]
元素,如果没有,则会创建唯一的id
。jQuery.cache[id]
的条目,如果没有创建一个空对象来存储该元素的数据。因此,如果您调用.data(key,value)
数据存储在窗口中,则您使用的jQuery实例将被定义。
如果parent
中有一个jQuery对象,iframe
中有一个jQuery对象,则由于随机数而有两个不同的expandos
。如果从iframe的元素上的父jQuery对象调用.data()
,则使用父项的expando
,并将数据存储在父项中。如果你然后使用iframes jQuery,然后在iframe的jQuery之前就找不到任何数据的同一元素上调用.data
,因为它一方面有另一个expando
,另一方面有数据存储在父窗口中。
因此,如果要在iframe中设置数据,则应使用iframes jQuery对象。
$('iframe')[0].contentWindow.jQuery("body").data( ... )
设置数据,然后可以再次从iframe内部检索该数据,因为这样您就可以使用相同的jQuery对象来设置和读取数据。
修改强>
一个额外的重要说明。因为数据与使用过的jQuery实例一起存储,所以不应该使用jQuery在另一个上下文中存储数据。当你用jQuery删除元素时,JQuery有一个清理方法,它删除了事件监听器并从jQuery.cache
中删除了数据。但是,如果您使用jQuery存储另一个上下文中的元素的数据,则此清理方法将失败(例如,如果您在iframe中加载另一个页面)。因此,只有在重新加载父数据时才会释放数据。