2012-02-20 59 views
11

在頁面上我有一個iframe。在這個iframe是我需要排序的項目的集合。所有的Javascript都在父頁面上運行。我可以通過上下文的iframe文檔中訪問列表,並創建排序:創建可在iframe中排序的jQuery UI

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

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

然而,試圖以實際項目進行排序時,我發現了一些異常行爲。只要一個項目被點擊,腳本的目標就會變成外部文件。如果您將鼠標移出iframe,則可以移動該項目並通過單擊將其放回,但不能在iframe內與其交互。

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

那麼,有沒有辦法做到我想做的事 - 最好,而不必去jQuery用戶界面代碼黑客身邊?

回答

9

動態添加jQuery和jQuery用戶界面的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的擁有和使用,以windowdocument引用的頁面,jQuery UI的是哪個加載。通過將jQuery/jQuery UI加載到iframe中,它具有正確的引用(對於iframe而不是外部文檔)並按預期工作。


更新2:原代碼片斷產生了微妙的問題:動態腳本標記的執行順序無法得到保證。我已經更新了它,以便在jQuery準備好之後加載jQuery UI。

我也將getify的代碼合併到load LABjs dynamically,所以不需要輪詢。

+0

謝謝!這對我來說似乎是一個乾淨的解決方法。你可以添加一個解釋或者一個鏈接,說明爲什麼這個解決了這個問題? – RARay 2012-06-28 14:11:04

+0

@RARay請參閱我的更新。 – 2012-06-28 14:34:39

+0

「這對我來說似乎是一個乾淨的解決方法。」真?這是直接投票。這是一個糟糕的生產解決方案。有*有*是比這更好的方式。 – kamelkev 2013-07-25 00:11:32

3

我不知道爲什麼你的代碼不工作。看起來應該是這樣。

也就是說,這裏有兩種可供選擇的方式來實現此功能:

  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

+0

當然,但這不是我的用例。我只控制父文檔。 – RARay 2012-02-21 16:53:25

+0

好點。我已經用第二種方式更新了我的答案,以實現此目的,即使它不回答問題,這也可能適用於您。 – 2012-02-21 17:59:58

+0

這是一個非常有趣的觀點,也是我沒有想到的。我不知道它是否適用於產生我的問題的更復雜的系統,但我一定會看看它。謝謝! – RARay 2012-02-21 18:04:11

5

在擺弄自己的JavaScript一點,運動監視器通過基本上爲jQuery用戶界面的自定義版本解決這個問題。他們修改了ui.mouse和ui.sortable,用代碼來替換文檔和窗口的引用,這些代碼爲相關元素獲取文檔和窗口。 document成爲this.element[0].ownerDocument

,他們有一個自定義的jQuery函數調用窗口(),這讓他們與this.element.window()或類似的替代window

+0

這就是我們現在處理它的方式。我基本上已經編寫了一個插件,可以使用可以工作的代碼擴展必要的功能。這很冒險,我擔心,這與我們的情況有關。你能提供一個資源的鏈接,讓其他人解決這個問題嗎? – RARay 2012-06-27 14:59:06

+0

嘿安德魯,你能發佈自定義jQuery文件的鏈接嗎? – 2013-02-20 09:27:37

+0

嘿,安德魯,你可以發佈這個鏈接,我認爲不適應這種方法。或者可能是一個指南。 – 2014-05-29 02:18:09

1

,而不是加載jQuery和jQueryUI的內嵌框架內和評估都在父母子女jQueryUI的互動 - 您可以簡單地泡鼠標事件給母公司文件:

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

$('.sortable', ifrDoc).on('mousemove mouseup', function (event) { 
    $(parent.document).trigger(event); 
}); 

這樣你就可以評估所有你的Javascript在父母的文檔上下文中。