2013-04-08 95 views
2

對於具有特定知識的人來說,這一切都與WordPress的「主題定製器」有關,儘管這不需要回答這個問題。Javascript:數據可以通過iframe雙向傳遞嗎?

基本上,我有一個頁面(在PHP中),其中包含一個適用於iframe內容的左側「窗格」,該窗格是屏幕的右側部分。

從概念上講,我打算使用jQuery draggable來通過拖動函數調整主背景圖像的CSS background-position。我需要在customize.php頁面上應用draggable(),將腳本排隊到那裏,然後操作iframe中的DOM。它需要在容器/父級別完成,因爲該級別的設置會更新X和Y座標並將其保存在存儲的設置中。

我想我需要也許是不可能的,但我不知道是否有可能用JavaScript做以下的

  1. 獲取的iframe
  2. 操作DOM的內容在iframe中,通過draggable()調整背景圖像並將background-position座標存儲爲數據屬性,然後將它們保存到適當的設置輸入字段。

在我的經驗中,從「父」操縱的iframe裏面的DOM /容器水平是困難的,我想知道如果有件事情我不知道,這是絕對不可能的,或者有一些解決方法嗎? (請注意,始發域是相同的,所以不會有任何跨域iframe問題)

+1

如果iframe和父域相匹配,你可以在兩者之間進行通信的。這就是TinyMCE和CKEditor等編輯器的工作原理。 js對象可以在兩者之間傳遞,但是由於內存泄漏和其他問題,您需要小心使用dom對象。如果你使用類似jQuery的庫,它也可以工作,但前提是上下文是正確的文檔。 – 2013-04-08 17:24:16

+0

附加說明。你不能得到可拖動的工作,從文檔到iframe。這是可能的,但它需要一些事件從iframe傳遞到文檔以及其他方式,以及一些額外的自定義。但通常是可能的。我有這樣的工作。但因爲這只是一個測試,我不知道我是否仍然擁有它。 – 2013-04-08 17:35:36

+0

感謝您的洞察力。如果你覺得它並且想分享代碼,我會很樂意接受它作爲一個回報,讓其他人看到相同的利益。 – Brian 2013-04-08 17:37:53

回答

2

這是我父母iframe通信的測試實現的簡化代碼。我添加了一些樣本如何使用。但我必須指出,它已經超出了我的實驗室部分,而且我目前還沒有時間來檢查它是否完全跨瀏覽器兼容。但如果不是,那麼只會做一些小的改變。 (編輯在當前鉻,ff和IE 6-9測試)

我希望這會幫助你與你的問題。但是,我現在不能保證它能夠完美地工作(但我很確定)。

代碼母公司

<!doctype html> 
<html> 
<head> 
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> 
    <title>index</title> 
    <script src="jquery.js" type="text/javascript" charset="utf-8"></script> 
    <script type="text/javascript" charset="utf-8"> 

    (function($, window, undefined) { 

     var iframe; 

     // the connector object the will be passed to the iframe and will be used as "API" 
     var parentConnector = { 
      _window : window, // a reference to the parents window (not really necessary but nice to have) 
      $ : $,    // a reference to the parents jQuery that can be accessed from the iframe (use with caution) 

      // here you will define you "API" for the parent (the functions you want to call from the iframe) 
      setElementValue : function(selector, value) { 
       $(selector).val(value); 
      } 

     } 

     // this function is called by the iframe to register the iframe in the parent 
     window.registerIFrame = function(iframeHelper) { 
      //if you have multible iframe in the parent you could change the code here to store them in e.g. an arrray or with a key in an object 
      iframe = iframeHelper; 

      // register the parent in the iframe 
      iframe.registerParent(parentConnector); 
     } 



     $(document).on("click",".slideUp",function(event) { 
      event.preventDefault(); 

      /* 
      call a function on the helper object, this is the savest way for the commincation because 
      there is it minimizes the risk to mix the differnt context 
      */ 
      iframe.slideUp(); 

      /* 
      This way would work at least in chrome, with the current version with jquery, but it relays the jQuery implementation 
      that the correct document is used. 
      */ 
      iframe.$(".info-from-parent").val("slideUp"); 

      /* 
      One thing you should NEVER do is the following: 

      iframe.$(".info-from-parent").append($("<div></div>")); 

      The reason you should not do this is because this mixes DOMElements of different context. 
      This will result in unexpected crashes/bahaviors in some browsers (but could work in others, or at least it will look like it would work) 
      */ 

     }); 


     // same as the slide down, it is just there to have some interaction sample 
     $(document).on("click",".slideDown",function(event) { 
      event.preventDefault(); 
      iframe.slideDown(); 
      iframe.$(".info-from-parent").val("slideDown"); 
     }); 


    })(jQuery, window); 

    </script> 
</head> 
<body> 
    <input type="text" class="info-from-iframe"><br> 
    <a href="#" class="slideUp">slideUp</a> <a href="#" class="slideDown">slideDown</a><br> 
    <iframe src="iframe.html"></iframe> 

</body> 
</html> 

代碼的iframe

<!doctype html> 
<html> 
<head> 
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> 
    <title>iframe</title> 
    <script src="jquery.js" type="text/javascript" charset="utf-8"></script> 
    <script> 

    (function($,window,undefined) { 

     //the connector object the will be passed to the parent and will be used as "API" 
     var iframeConnector = { 

      _window : window,  // a reference to the iframes window (not really necessary but nice to have) 
      _parent : undefined, 
      $ : $,    // a reference to the iframes jQuery that can be accessed from the parent (use with caution) 

      // this function is called by the parent to register the parent in the iframe 
      registerParent : function(parent) { 
       this._parent = parent; 
      }, 

      /* here you will define you "API" for the iframe (the functions you want to call from the parent)*/ 
      slideUp : function() { 
       $(".test").slideUp(); 
      }, 

      slideDown : function() { 

       $(".test").slideDown(); 
      }, 

      setElementValue : function(selector, value) { 
       $(selector).val(value); 
      } 

     }; 

     // register the iframe in the parent 
     window.parent.registerIFrame(iframeConnector); 

     $(document).mousemove(function(event) { 
      //use the parents "API" to call a function in the parent 
      iframeConnector._parent.setElementValue(".info-from-iframe", event.clientX+", "+event.clientY); 
     }); 

    })(jQuery,window); 


    </script> 
</head> 
<body> 
    <input type="text" class="info-from-parent"><br> 
    <div class="test"> 
     iframe 
    </div> 
</body> 
</html>