Call JS Function from hype document that is linked to the parent HTML document

I have an HTML file that a my main.js is linked to. I also have a hype document placed on this HTML page via JS (not iFrame). From within hype I would like to call functions and even pass a variable along from hype to the functions declared in the main.js file.

I have seen a few posts that dance around this subject but a solution is never declared.

Is there a forum post that I have not found that has a solution declared to accomplish this?

As long as the Hype animation is not in an iframe as you say, then you can access any globally-scoped items within the Hype-declared functions. There's not really anything special you need to do.

Let's say your main.js has code like:

var favoriteNumber = 10;
function helloWorld(name) {
    console.log("hi, " + name + ". My favorite number is " + favoriteNumber);
}

And on your .html page you have an exported hype animation. It would look something like:


<script src = "main.js"></script>


<div id="index_hype_container" class="HYPE_document" style="margin:auto;position:relative;width:600px;height:400px;overflow:hidden;">
    <script type="text/javascript" charset="utf-8" src="index.hyperesources/index_hype_generated_script.js?76586"></script>
</div>

Within the .hype document in Hype itself you made an On Mouse Click handler for an element to Run JavaScript with a function. You can get at the main.js stuff via:

// element - DOMHTMLElement that triggered this function being called
// event - event that triggered this function being called
function untitledFunction(hypeDocument, element, event) {
    favoriteNumber = 20;
    helloWorld("Jason");
}

The output when clicking on the element would be:

hi, Jason. My favorite number is 20
1 Like

I have the following: (all within the normal hype function call (function testClick(hypeDocument, element, event))

hypeDocument.getElementById("textLink02").onclick = function() {
console.log('clicked!');
console.log(window);
initVideoTab(2);
};

clicked gets written to the console, the window gets written to the console.

But then:

Uncaught ReferenceError: initVideoTab is not defined
at HTMLDivElement.hypeDocument.getElementById.onclick (eval at m (pladdv1_hype_generated_script.js:6), :5:2)

I'd need to see your actual code/document, but based on the error you have not properly defined initVideoTab() in the global scope (aka window scope) in your main.js.

You can look at the logged window object to see if initVideoTab is there. It would probably be easier to log window.initVideoTab. If it is not there you have not defined it correctly.

Unrelated to that error, I would ask why you are adding an onclick handler within hype's click handler? This is an atypical pattern.

Was absolutely a scoping issue. Function that I was trying to call was not in global scope and I had to end up defining the function as window.initVideoTab(2) .

To your other point about the means in which I am calling it, and I don't want to mucky up this thread with multiple topics, but the function will actually be called from a symbol. I am guessing the better way to call it would be maybe from the document head? Just literally defining an event listener on the element's ID and calling it that way. Would you agree?

Thanks for your assistance. It got me to the solution with a little help from a teammate.

what @jonathan (may :wink: ) have meant is that you're not using a hypebehaviour on the element. instead you set up your own eventlistener ... but it's ok anyhow.

an easy way and first small approach to not populate the window-object is to create a js-object on the window and store anything global there ...

Great, I'm glad you were able to resolve the original problem.

I'm a little unclear on the exact setup, but it sounds like you have multiple symbol instances and want different behavior for a contained element in each?

In this case this is a reasonable use to make your own onclick handlers; I was just worried because we often see folks making their own handlers when it is probably more appropriate to do so within Hype's UI :slight_smile:.

I'd definitely do it within the Hype structures. If you do it in the Head HTML you'd have to wait until the Hype animation is done loading which makes the code a bit more difficult and less able to be moved around (since you need to move the head code wherever you place it too).

One thing to be aware of is that you can't correctly have an element with an ID within a symbol that has multiple instances. IDs are scoped to the entire page, so duplicates won't be able to be found correctly. Typically within a symbol you'd give an element a class name. The symbol element itself may have an ID. So then you'd lookup the inner element by using the getElementsByClassName() that is called on the symbol instance element.

One setup that works well to have symbol instance-specific behavior is to add Additional HTML Attributes in the Identity Inspector. Then using an On Symbol Load event (in the Symbol Inspector) you can look these up on the element via getAttribute() and do stuff based on it.

Hopefully those are some pointers to help -- but if the other parts are working fine then feel free to not worry about any of it! :slight_smile: .