Hello everyone,
I am newbie in Hype and have a, for my project important question:
Is it possible from a hype page, which is included as iframe in a web page, to control the underlying page?
If so how?
Thanks a lot for your help,
Volker
Hello Volker,
Great to see you active in the community again!
I’m curious to know more about your project involving Hype and iframes. When you talk about controlling the underlying page from a Hype page in an iframe, it sounds like a complex setup. Could you help us understand exactly what you mean by “control”? Are there specific elements or functionalities on the parent page you’re aiming to interact with?
Also, it’s crucial to know about the hosting situation of both the Hype page and the parent web page. Are they on the same domain? This detail matters a lot due to cross-origin policies in web browsers.
And speaking of the iframe setup, is the iframe directly embedded in the Hype page, or is it inside another iframe? The hierarchy here could make a difference in how you’d approach this.
Understanding all this would really help in guiding you to the right solution.
Max
P.S. Generally, to control a parent page from an iframe, you’d look into using JavaScript for cross-document communication. This could involve methods like postMessage for secure message passing, especially if the documents are on different domains. If they're on the same domain, direct DOM manipulation could be an option. If it’s only signals and you control both ends you can use something like Hype Global Behavior
Hello Max,
thank you very much for your quick and detailed answer.
The idea is to control a web page via a menu built in Hype and included in an iframe.
Both should be on the same server.
We have a lot of different modules that are all controlled by the same menu. The menu needs to be adjusted more often, so currently we have to edit each module individually each time.
To avoid this, we want to build the menu in Hype and include it as an iframe in the individual modules.
Do you see a possibility?
Thanks for your help,
many greetings,
Volker
Certainly, Volker! Since both the menu built in Hype and the individual modules are hosted on the same server, this simplifies the process considerably. Here’s a step-by-step guide and a code example to help you achieve what you’re looking for:
Step 1: Define a Custom Behavior in Your Hype Document
- Open your Hype document.
- Go to the 'Scene Inspector' panel.
- Scroll down to the 'Behaviors' section.
- Click on the ‘+’ button to add a new behavior.
- Give your behavior a name, e.g., “TriggerFromIframe”.
- Define the actions you want this behavior to perform when triggered.
Step 2: Embed Your Hype Document as an Iframe
Embed the Hype document that you’ve just set up a custom behavior in, into your webpage as an iframe. Ensure that the id
attribute of the iframe is set, as you will need this to reference it in your JavaScript code. For example:
<iframe id="hypeIframe" src="path_to_your_hype_document.html" width="100%" height="500px"></iframe>
Step 3: Write the JavaScript Function to Trigger the Custom Behavior
In your Hype menu document (the one that you’re using to create the menu), insert the following JavaScript function:
function triggerCustomBehaviorInIframe(hypeDocument, element, event) {
var iframe = document.getElementById('hypeIframe');
if (iframe && iframe.contentWindow.HYPE) {
// Fetching the first Hype document within the iframe
var firstKey = Object.keys(iframe.contentWindow.HYPE.documents)[0];
// Triggering the custom behavior
iframe.contentWindow.HYPE.documents[firstKey].triggerCustomBehaviorNamed('TriggerFromIframe');
} else {
console.error('Iframe or HYPE not found');
}
}
Step 4: Attach the JavaScript Function to a Menu Item
- Select the menu item within your Hype menu document.
- Go to the 'Actions' panel.
- Add an ‘On Mouse Click’ action.
- Choose ‘Run JavaScript…’ and select the function you just created.
Step 5: Test Your Setup
Now, when you click the menu item in your Hype menu document, it should trigger the custom behavior in the Hype document embedded within the iframe.
Please ensure that both documents are served from the same domain and protocol to avoid any cross-origin issues. If everything is set up correctly, this should work seamlessly for you.
Alternatively you can use Hype Global Behavior and the entire process even works across domains
Let me know if you need a postmessage example.
If you want to directly call the Tumult Hype API to jump to a specific scene, you can streamline the function like this:
function jumpToSceneInIframe(hypeDocument, element, event) {
var iframe = document.getElementById('hypeIframe');
if (iframe && iframe.contentWindow.HYPE) {
// Fetching the first Hype document within the iframe
var firstKey = Object.keys(iframe.contentWindow.HYPE.documents)[0];
var hypeDoc = iframe.contentWindow.HYPE.documents[firstKey];
// Jumping to the scene named “Some Scene Name”
hypeDoc.showSceneNamed('Some Scene Name');
} else {
console.error('Iframe or HYPE not found');
}
}
Here is a promised based function to get the Hype document of a nested iFrame:
Head HTML of parent (Menu):
function HypeDocumentLoad(hypeDocument, element, event) {
hypeDocument.getIframeHypeDocument = function(selector) {
return new Promise(function(resolve, reject) {
// Get the current scene element using hypeDocument.currentSceneId()
var currentSceneId = hypeDocument.currentSceneId();
var currentSceneElement = document.getElementById(currentSceneId);
var iframe;
if (selector) {
iframe = currentSceneElement.querySelector(selector);
} else {
iframe = currentSceneElement.querySelector('iframe');
}
if (iframe && iframe.contentWindow.HYPE) {
var firstKey = Object.keys(iframe.contentWindow.HYPE.documents)[0];
var hypeDoc = iframe.contentWindow.HYPE.documents[firstKey];
if (hypeDoc) {
resolve(hypeDoc);
} else {
reject('Hype Document not found inside iframe');
}
} else {
reject('Iframe or HYPE not found');
}
});
};
}
if("HYPE_eventListeners" in window === false) { window.HYPE_eventListeners = Array(); }
window.HYPE_eventListeners.push({type: "HypeDocumentLoad", callback: HypeDocumentLoad});
Now you can use code like this in your Hype functions of the parent (Menu):
// If you want to target a specific iframe with a CSS selector
hypeDocument.getIframeHypeDocument('.someClass')
.then(function(iframeHypeDocument) {
iframeHypeDocument.showSceneNamed('Some Scene Name');
})
.catch(function(error) {
console.error(error);
});
// If you want to target the first iframe in the current scene
hypeDocument.getIframeHypeDocument()
.then(function(iframeHypeDocument) {
iframeHypeDocument.showSceneNamed('Some Scene Name');
})
.catch(function(error) {
console.error(error);
});
This only works as long as the Hype documents involved are on the same domain.