Error trying getting element by id, How shopify compiles javascript files?

Solved
Tourist
10 0 1

 

Hello everyone!

I am new at shopify and i am trying understanding how shopify handles the javascript files.

I've created a javascript file named theme.js and added inside the <header> tag of my theme.liquid layout file.

 

{{ 'theme.js' | asset_url | script_tag }}

I also have added <a> tag with an id="cart" inside my <body> tag of my theme.liquid layout file.

 

<a id="cart" href="/cart">cart</a>

 

That's my theme.js file.

 

var amordami = window.amordami || {};

amordami.Theme = (function() {

	var _init = function() {
		document.getElementById("cart").style.display = 'none';
	};

	return {
		init : _init
	};

}());

window.onload = amordami.Theme.init();

But i am getting an error when i run it.image.png

I've noticed that when add my javascript file in this format...

 

<script src="{{ 'theme.js' | asset_url }}" defer="defer"></script>

Everything goes ok. No errors.

Why? Can anyone explain more about the shopify file compililation. How are javascript files handle by shopify?

 

 

0 Likes

Success.

Shopify Expert
2678 65 668

Hi there, it's not Shopify specific -- your problem is in this line:

 

window.onload = amordami.Theme.init();

It actually executes the amordami.Theme.init function and assigns its result to window.onload.

This javascript code is loaded (and immediately run) from the <head> when  the body of the document is not loaded yet, therefore there is no element you're trying to target.

 

When you use defer, your javascript is only loaded and run after entire main document is  already in, so it works fine.

 

That line of code should be like this, to actually assign the function init, not the result of its execution.

window.onload = amordami.Theme.init;

 

However, I'd suggest not to use window.onload -- it's a single function and it's value can be overwritten by other code (Apps, other edits). You may end up with: 

window.onload = amordami.Theme.init;
....
window.onload = some.plugin.init;

And only the second function will be executed :(

 

Better listen for DOMContentLoaded or load events -- it's possible to bind several event handlers and each of them will be run.

/Sorry for multiple edits /

Want to hire me to tweak a theme? Mail me at tairli@yahoo.com!
My post solved your problem? Like it!
1 Like
Tourist
10 0 1

Thank you so much! This worked fine! Thank you for the advice, i am going to do the changes to listen load events.

0 Likes