How to Load and Unload (or Reset) Embedded Hype Widgets

I’m trying to figure out how to accomplish an idea that I have, perhaps someone can help.

The concept is that if you have an embedded Hype widget, such as the image gallery in my attached project file example, I want it to reset upon an user action. I can easily make it fade in and fade out using it as a waypoint via the On Enter Viewport and On Exit Viewport action.

But if the user were to move (horizontally) clicking through the embedded gallery, away from the first image that the gallery starts with, and then they scroll the webpage away from the embedded gallery (so it fades out), and then scroll back to it, the images in the gallery will currently remain where the user left off.

However, I want it to reset, so that if they scroll the webpage away and then scroll back to the gallery, or click on the webpage menu item (the “Click On This” in my sample), that auto-scrolls the page to where the gallery is, then the gallery should start with the first photo again. There’s no action to “reload” an embedded widget, so I assume it will require javascript code to reset the gallery.

EmbedWidget.hype.zip (168.6 KB)

The main problem is that the viewport is to the "document" so while it would be intuitive you could set the waypoint on the child, that won't work. Maybe there will be a way to get that in the future.

So that would leave the option of reloading the URL (which still would require javascript), or communicating to the iframe via postmessage.

Actually the idea of channeling a custom behavior through an iframe sounds pretty useful. Here's some code for you:

On the child side, simply add this to the Head HTML:

	<script>
	
	function documentLoadedCallback(hypeDocument, element, event) {
		// create a handler for messages
		var postMessageHandler = (function (event) {
			try {
				// we expect it to be in a specific record format
				var info = JSON.parse(event.data);
				if(info.type == "trigger") {
					// if it is a trigger, then use the customBehaviorName field
					hypeDocument.triggerCustomBehaviorNamed(info.customBehaviorName);
				}
			} catch (exception) {
				console.log(exception);
			}
		});
	
		// add listeners for postmessage
		if(window.addEventListener) {
			window.addEventListener("message", postMessageHandler, false);
		} else {
			window.attachEvent("onmessage", postMessageHandler);
		}

		return true;
	}
	
	// setup the postmessage listener once when this document loads
	if("HYPE_eventListeners" in window === false) {
		window.HYPE_eventListeners = Array();
	}
	window.HYPE_eventListeners.push({"type":"HypeDocumentLoad", "callback":documentLoadedCallback});
	
	</script>

And then on the on enter viewport action for the iframe element, add this code for a run javascript action (changing the customBehaviorName to whatever in the child you want to respond to):

	// name of custom behavior to trigger
	var customBehaviorName = "resetMainTimeline";
	
	// convert to a specific format that will be parsed by the child
	var data = JSON.stringify({ type: "trigger", customBehaviorName: customBehaviorName });
	
	// search only the element that triggered it, but if there's no specific element use the document scope
	var parentElement = element;
	if(parentElement == null) {
		parentElement = document;
	}
	
	// find the actual iframe element
	var iframes = element.getElementsByTagName("iframe");
	for(var i = 0; i < iframes.length; i++) {
		// communicate to the child
		iframes[i].contentWindow.postMessage(data, "*");
	}
1 Like