0

I am trying to implement JavaScript within an iframe from the parent page. I read Invoking JavaScript code in an iframe from the parent page, however, get the following error.

Error: Permission denied to access property "showIt"
document.getElementById('targetFrame').contentWindow.showIt();

I've tried implementing this both on jsfiddle as well as my server (don't know if it matters, but it uses https), but get the same results. I've also tried removing the $(function(){}) wrapper on the child iframe, but no change.

My actual application is described below.

How can this be accomplished?

My Application:

I have my parent page https://jsfiddle.net/5f4ct5ph/6/) which contains an iframe.

<iframe width="100%" height="300" src="https://jsfiddle.net/5f4ct5ph/5/embedded/result/" id="targetFrame"></iframe>

<button id="show">Show</button>
<button id="hide">Hide</button>

$(function () {
    $('#show').click(function () {
        document.getElementById('targetFrame').contentWindow.showIt();
    });
    $('#hide').click(function () {
        document.getElementById('targetFrame').contentWindow.hideIt();
    });
});

The iframe page (https://jsfiddle.net/5f4ct5ph/5/) contains a tinymce editor.

<div id="content">Initial content goes here</div>

#content {height:200px;width:400px;border: 1px solid;}

$(function () {
    tinymce.init({
        selector: "#content",
        width : 400,
        height: 200,
        setup : function(ed) {
            ed.on('init', function(e) {
                e.target.hide();
            });
        }
    });

    function showIt() {
        tinymce.get('content').show();
    };

    function hideIt() {
        tinymce.get('content').hide();
    };
});
Community
  • 1
  • 1
user1032531
  • 24,767
  • 68
  • 217
  • 387

2 Answers2

1

Normally, if iframe and parent are on same domain, it should work, but there are restriction to communication from window to window. You can try using postMessage, like this:

In your parent page, in the click event, instead of calling the function directly, you could do this:

child_window = document.getElementById('targetFrame').contentWindow;
child_window.postMessage("showit" or "hideit", your_domain);

The in you iframe:

window.addEventListener("message", check_message, false);

function check_message(event){
    switch(event.data){
        case "showit":
            showIt();
            break;
        case "hideit":
            hideIt();
            break;
        default:
            breaks;
    }

Make sure your functions showIt and hideIt are available from where you call check_message.

Again, there may be another problem, it's hard to tell with the embedded jsfiddle, but in any case, when dealing with iframes and javascript, postMessage is often more flexible and secure than accessing functions and variables directly.

Julien Grégoire
  • 16,864
  • 4
  • 32
  • 57
1

fiddle.jshell.net (the parent document domain) is different to jsfiddle.net (your iframe domain).

I've changed your code to point to the jshell.net url instead (You can get this by using the URL of the frame in the bottom right of jsfiddle rather than the address bar).

https://jsfiddle.net/GarryPas/5f4ct5ph/7/

showIt() and hideIt() don't seem to be defined (because they are inside an anonymous function). Change this:

$(function () {
    ...

    function showIt() {
        tinymce.get('content').show();
    };

    function hideIt() {
        tinymce.get('content').hide();
    };
});

To this:

$(function () {
    ...
});

function showIt() {
    tinymce.get('content').show();
}

function hideIt() {
    tinymce.get('content').hide();
}

Then remove my alerts and put back your original code which I commented out.

garryp
  • 5,508
  • 1
  • 29
  • 41