【问题标题】:Creating a jQuery UI sortable in an iframe在 iframe 中创建可排序的 jQuery UI
【发布时间】:2012-03-11 07:11:59
【问题描述】:

在一个页面上我有一个 iframe。在这个 iframe 中是我需要排序的项目集合。所有的 Javascript 都在父页面上运行。我可以访问 iframe 文档中的列表并使用上下文创建可排序:

var ifrDoc = $( '#iframe' ).contents();

$( '.sortable', ifrDoc ).sortable( { cursor: 'move' } );

但是,在尝试对项目进行实际排序时,我遇到了一些异常行为。一旦单击某个项目,脚本的目标就会更改为外部文档。如果将鼠标从 iframe 上移开,则可以通过单击来移动项目并将其放回原处,但不能在 iframe 内与之交互。

示例:http://robertadamray.com/sortable-test.html

那么,有没有办法实现我想要做的 - 最好不必在 jQuery UI 代码中到处乱窜?

【问题讨论】:

    标签: jquery-ui iframe jquery-ui-sortable


    【解决方案1】:

    而不是在 iFrame 中加载 jQuery 和 jQueryUI 并评估父级和子级中的 jQueryUI 交互 - 您可以简单地将鼠标事件冒泡到父级文档:

    var ifrDoc = $( '#iframe' ).contents();
    
    $('.sortable', ifrDoc).on('mousemove mouseup', function (event) {
        $(parent.document).trigger(event);
    });
    

    这样您就可以在父文档上下文中评估您的所有 Javascript。

    【讨论】:

      【解决方案2】:

      将 jQuery 和 jQuery UI 动态添加到 iframe (demo):

      $('iframe')
          .load(function() {
              var win = this.contentWindow,
                  doc = win.document,
                  body = doc.body,
                  jQueryLoaded = false,
                  jQuery;
      
              function loadJQueryUI() {
                  body.removeChild(jQuery);
                  jQuery = null;
      
                  win.jQuery.ajax({
                      url: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js',
                      dataType: 'script',
                      cache: true,
                      success: function () {
                          win.jQuery('.sortable').sortable({ cursor: 'move' });
                      }
                  });
              }
      
              jQuery = doc.createElement('script');
      
              // based on https://gist.github.com/getify/603980
              jQuery.onload = jQuery.onreadystatechange = function () {
                  if ((jQuery.readyState && jQuery.readyState !== 'complete' && jQuery.readyState !== 'loaded') || jQueryLoaded) {
                      return false;
                  }
                  jQuery.onload = jQuery.onreadystatechange = null;
                  jQueryLoaded = true;
                  loadJQueryUI();
              };
      
              jQuery.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
              body.appendChild(jQuery);
          })
          .prop('src', 'iframe-test.html');
      

      更新: Andrew Ingram is correct jQuery UI 持有并使用对加载 jQuery UI 的页面的 windowdocument 的引用。通过将 jQuery / jQuery UI 加载到 iframe 中,它具有正确的引用(对于 iframe,而不是外部文档)并按预期工作。


      更新 2: 原始代码 sn-p 有一个微妙的问题:动态脚本标签的执行顺序无法保证。我已经更新了它,以便在 jQuery 准备好之后加载 jQuery UI。

      我还将getify的代码合并到load LABjs dynamically,这样就不需要轮询了。

      【讨论】:

      • 谢谢!这对我来说似乎是一个足够干净的解决方法。您能否添加解释或链接,说明为什么这可以解决问题?
      • “这对我来说似乎是一个足够干净的解决方法。”。真的吗?这是直接投票。这是一个可怕的生产解决方案。 必须有比这更好的方法。
      • @kamelkev 演示代码仅用于说明答案(将 jQuery 和 jQuery UI 加载到 iframe 中);无法保证生产就绪。不过,我已经更新了答案,使其不使用轮询。
      【解决方案3】:

      在使用过他们的 javascript 之后,Campaign Monitor 基本上通过自定义版本的 jQuery UI 解决了这个问题。他们修改了 ui.mouse 和 ui.sortable 以使用获取相关元素的文档和窗口的代码替换对文档和窗口的引用。 document 变为 this.element[0].ownerDocument

      他们有一个名为 window() 的自定义 jQuery 函数,可以让他们将 window 替换为 this.element.window() 或类似的。

      【讨论】:

      • 这就是我们现在的处理方式。我基本上已经编写了一个插件,它使用可以工作的代码扩展了必要的功能。这很骇人听闻,而且我担心,具体到我们的情况。您能否提供一个资源链接,让其他有此问题的人能够解决它?
      • 你好 Andrew,你能贴出自定义 jQuery 文件的链接吗?
      • 嘿安德鲁,你能发布一个链接吗,我认为这种方法不好。或者指南。
      【解决方案4】:

      我不知道为什么您的代码不起作用。看起来应该是。

      也就是说,这里有两种实现此功能的替代方法:

      1. 如果可以修改 iframe

        将您的 JavaScript 从父文档移动到 iframe-test.html。这可能是最简洁的方式,因为它将 JavaScript 与其实际执行的元素结合在一起。

        http://dl.dropbox.com/u/3287783/snippets/rarayiframe/sortable-test.html

      2. 如果只控制父文档

        使用 jQuery .load() 方法而不是 HTML iframe 来获取内容。

        http://dl.dropbox.com/u/3287783/snippets/rarayiframe2/sortable-test.html

      【讨论】:

      • 当然,但这不是我的用例。我只控制父文档。
      • 好点。我已经用第二种方法更新了我的答案,这可能对你有用,即使它没有回答问题。
      • 这是一个非常有趣的观点,也是我没有想到的。我不知道它是否适用于引发我的问题的更复杂的系统,但我肯定会看看。谢谢!
      猜你喜欢
      • 2013-07-12
      • 1970-01-01
      • 2014-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 1970-01-01
      相关资源
      最近更新 更多