如何在iFrame主体标签上设置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被用作属性来存储DOM元素的标识符。

使用.data(key,value)在元素中存储数据时,jQuery执行以下步骤:

  1. 检查element[jQuery.expando]中的元素是否有id,如果没有,则创建一个唯一的id
  2. 检查是否有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

最新更新