【问题标题】:Javascript: Can data be passed bi-directionally through an iframe?Javascript:数据可以通过 iframe 双向传递吗?
【发布时间】:2013-03-30 21:11:17
【问题描述】:

对于任何了解它的人来说,这一切都与 WordPress“主题定制器”有关,尽管没有必要回答这个问题。

基本上,我有一个页面(在 PHP 中),其中包含一个左侧“窗格”设置,适用于 iframe 的内容,即屏幕的右侧部分。

从概念上讲,我希望使用jQuery draggable 使主背景图像的CSS background-position 通过可拖动功能进行调整。我需要在customize.php 页面上应用draggable(),将脚本排入队列,然后在iframe 中操作DOM。它需要在容器/父级别完成,因为在该级别有一个设置将更新 X 和 Y 坐标并将它们保存在存储在那里的设置中。

我认为我需要的东西可能是不可能的,但我想知道是否可以使用 javascript 来执行以下both

  1. 获取 iframe 的内容
  2. 在 iframe 内操作 DOM,通过 draggable() 调整背景图像并将 background-position 坐标存储为数据属性,然后将它们保存到适当的设置输入字段。

根据我的经验,从“父”/容器级别操作 iframe 内的 DOM 是很困难的,我想知道是否有一些我不知道的东西,这绝对是不可能的,或者有一些解决方法? (注意源域是一样的,不会有跨域iframe问题)

【问题讨论】:

  • 如果 iframe 的域和父域匹配,则可以在两者之间进行通信。这就是 TinyMCE 和 CKEditor 等编辑器的工作方式。 js 对象可以在两者之间传递,但是由于内存泄漏和其他问题,您需要注意 dom 对象。如果你使用像 jQuery 这样的库,它也可以工作,但前提是上下文是正确的文档。
  • 附加说明。您无法从文档到 iframe 进行开箱即用的可拖动工作。这是可能的,但它需要一些事件从 iframe 传递到文档,反之亦然,以及一些额外的定制。但一般来说是可能的。我有这样的工作。但因为这只是一个测试,我不知道我是否还有它。
  • 感谢您的洞察力。如果您找到它并想​​共享代码,我会很乐意接受它作为答案,以帮助其他希望这样做的人。
  • 但无论哪种方式,这听起来都是可能的,这主要是我要问的。
  • 我重读了您的问题,并认为我误解了它。您只想使背景图像可移动,而不是将元素从父级拖动到 iframe?我只是问,因为那样你就不需要做太多工作了。

标签: javascript wordpress dom web-applications iframe


【解决方案1】:

这是我的父 iframe 通信测试实现的简化代码。我添加了一些示例如何使用它。但我必须注意它不在我的实验室部分,我目前没有时间检查它是否完全跨浏览器兼容。但如果不是,则只需要做一些小的更改。 (EDIT在当前的 chrome、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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 2020-01-19
    • 1970-01-01
    相关资源
    最近更新 更多