如何在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执行以下步骤:

  1. 检查是否存在与element[jQuery.expando]中的element[jQuery.expando]一起存储的id ,否则它会创建唯一的id
  2. 检查是否有一个带有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