Call function from iframe

Hey guys, I have an iframe containing a hype document within my resources folder.

<iframe class="content" src="${resourcesFolderName}/index.html" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

I found this script listening to every klick made in this iframe:

<script>
$(document).ready(function(){
    $("iframe").load(function(){
        $(this).contents().on("mousedown, mouseup, click", function(){          
            alert("Clicked");
        });
    });
});
</script>

All working perfectly so far. I would now like to execute a function called resetTimer in my library, looking like:

function resetTimer() {

    window.tenmins = 10000;
    clearTimeout(window.timer_10_mins);

    window.timer_10_mins = setTimeout(function () {

            hypeDocument.showSceneNamed('screensaver', hypeDocument.kSceneTransitionInstant);
        }, tenmins)

    alert('done');
}

I found this code in Calling a function in Hype from an iframe
I added what jonathan's suggestion to my code, now looking like:

$(document).ready(function(){
    $("iframe").load(function(){
        $(this).contents().on("mousedown, mouseup, click", function(){          
            alert("Clicked");
            window.parent.HYPE.documents["index"].functions().resetTimer();
        });
    });
});

In preview mode, the function executes, I see the "clicked"-alert, the "done"-alert, but it does not reset my timer to 10 mins. When I export it, it does not execute at all, though i have inserted the document name for "index", which by the way, does also not work for the solution in Calling a function in Hype from an iframe

Any ideas, what is wrong in here?

EDIT: I created a minimal version of my file and attached it to this postminimal_example.hype.zip (158.2 KB)

Have a look at Hype Global Behavior. It might help…

1 Like

There's probably two things happening here:

  1. This index.html file itself doesn't exist in your resources folder, so it is returning a 404 error.

  2. From a quick glance, it appears that browser behavior is different if you open the export as a file:/// or serve via HTTP. If opened as a file, nothing seems to happen. When served via HTTP it will work correctly. Based on your description I assume you are opening as a file.

My basic recommendation would be to always test using a web server* and to always keep the developer console log open, as this can often pinpoint CORS or other errors when dealing with iframes. Browser behavior around this is pretty quirky.

* The easiest web server is to open the Terminal, cd into your export directory, run python -m SimpleHTTPServer and then open http://localhost:8000 .

@jonathan thank you again! you're right, this one is supposed to run local, opening up a browser in kiosk mode every time the system starts. And I actually dont have the possibility tun open a localhost everytime.

In this iframe I am actually opening another hype project from my resources folder, the index.html was just made to test the setup.

Further, testing this in preview mode directly from hype, the timer does not set back so far.

do you think this is even possible in this project?

I'm not sure what you mean by this, specifically "set back so far?" Can you elaborate on what you expect to see and what is happening?

@jonathan I would like to reset the timer by each click in the iframe. in my tests in hype preview mode the timer is cleared but not set again.

@jonathan in my minimal example clicking the button and clicking the iframe calls the same function from my library. Clicking the button works perfectly, but when clicking on the iframe my console says:

VM32:16 Uncaught TypeError: Cannot read property 'showSceneNamed' of undefined
at eval (eval at m (index_hype_generated_script.js?30141:6)

Or use whisk.app which runs better than SimpleHTTPServer

1 Like

Also I would scrap the way you are doing it and use postMessage.
I have also put the code inside a normal rectangle. HTML widgets add a layer of iframe which will break things like this.

minimal_example.hype 2.zip (97.4 KB)

1 Like

Ha, I had not thought about that as an easy solution!

1 Like

This means that the object you are calling showSceneNamed on has not been defined; this is likely the hypeDocument object. I'm guessing that the issue is basically that your call looks something like:

window.parent.HYPE.documents["index"].functions().resetTimer();

And the function signature for resetTimer() looks like:

function resetTimer(hypeDocument, element, event)

You are not passing any arguments into the function, so stuff like the hypeDocument is not defined. Therefore when you try to call a method on it, you get that error. You'll want to pass arguments into the call like:

var myHypeDocument = window.parent.HYPE.documents["index"];
myHypeDocument.functions().resetTimer(myHypeDocument);

Alternatively @MarkHunte's strategy may work better - and I believe @MaxZieb's earlier advice uses this technique under the hood and is made for such circumstances.

Thank you @jonathan and @MarkHunte for helping me out with this. Tried your suggestion @MarkHunte and it works perfectly when running the project using a web server. As it is running locally and I have to figure out whether opening a web server is possible, i chose @MaxZieb s advice from Remove Event Listen on Scene Load - Using JavaScript with Hype - Tumult Forums the onmouseup-event meanwhile.

Thank you guys again, you're awesome!

2 Likes