如何在iFrame body标签上设置jQuery data()并从iFrame中检索它?
我试图在我创建的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。
expando用作存储DOM元素的标识符的属性。
当您在元素中使用.data(key,value)
存储数据时.data(key,value)
jQuery执行以下步骤:
- 检查是否存在与
element[jQuery.expando]
中的element[jQuery.expando]
一起存储的id
,否则它会创建唯一的id
。 - 检查是否有一个带有
jQuery.cache[id]
的条目,如果没有创建一个空对象来存储该元素的数据。
因此,如果调用.data(key,value)
,数据将存储在窗口中,您使用的jQuery实例将被定义。
如果parent
有jQuery对象, iframe
有一个jQuery对象,则由于随机数,它们有两个不同的expandos
。 如果从iframe元素上的父jQuery对象调用.data()
,则使用父对象的expando
,并将数据存储在父对象中。 如果你然后使用iframes jQuery然后在iframe的jQuery之前调用.data
,那么jQuery将找不到任何数据,因为它一方面有不同的expando
,另一方面数据存储在父窗口中。
因此,如果要在iframe中设置数据,则应使用iframes 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的主体然后检索它: http : //jsbin.com/ecenij/1/edit