proper way to run jquery-based script on page load?

New Member
7 0 0

I have some custom form fields I am adding to a product and I am including some swatch images that will also modify the selector. One of the behaviors of the swatch selector is that it will mark the current item selected. The select does not have a 'blank' option and shopify seems to 'preserve' selected items on a reload. Thus I want to mark the selected swatch after the page loads based on the value currently selected. (this can be done with the same function that highlights the swatch when clicked)

Normally I would do this via jQuery's .ready() function but it seems that if I put a $.ready() or $() syntax in the global scope of the script tag, the console reports '$ is not defined' so apparently jquery is either lazyloaded or is on some kind of delayed/deferred/async load that isn't present when the script tag is rendered by the browser. (or at least by chrome)
I tried using window.load (which is dangerous as you may over-ride a prior definition of window.load) but got the same error due to jQuery functionality in my code.  I also tried document.addEventListener("DOMContentLoaded"...) and window.addEventListener("load"...) with similar results.

Does shopify have some 'working' way to run a script when everything is ready and jquery is properly loaded?

0 Likes
Tourist
10 1 1

`$ is not defined` is a error that you can receive if the code that you are writing runs before jQuery is loaded. You haven't stated where jQuery is being declared in the HTML markup? If it is at the bottom of the html markup at the closing `body` tag then that is the problem. Because inline scripts will probably load before then.

 

You can move the jQuery script tag to the `head` tag to see if it fixes the issue.

1 Like
Tourist
11 0 1

Most probably Jquery not yet loaded or not available. 
Try checking it in your console just copy paste that.

if (typeof jQuery == 'undefined') {
console.log("Jquery not available");
}
else{
console.log('Jquery Ver:' + jQuery.fn.jquery);
}

and Asjas is correct. Try putting it before the closing body tag. 

1 Like
New Member
23 0 0

It's in the product-template.liquid where I'm trying to pre-select icons added as swatch selectors on the form based on whatever is the selected item (usually the first/default) on the form.

A setTimeout does allow the code to work, but that's unreliable. It should be well below any header content unless Shopify is loading jquery in the bottom of the body somewhere.

Mind you, I'm not trying to execute the code as it's rendered. I'm trying to use something such as the onLoad handler. That's kind of the point of the post. But jQuery isn't loaded yet so I'm wondering what the recommended way to do it is. In most cases on other sites I have developed, jQuery is loaded in the header so it's already available by the time any body javascript is rendered, thus you can call the $(); functionality to add commands to the jQuery.ready(); queue. But this does not seem to be the case with how Shopify is loading jQuery. So I'm wondering how people do it on shopify.

 

As far as moving it to the head, the code only effects conditional block in forms for specific products. While I could probably include the code in 'every' product by default, that would kind of be self-defeating as it would add to the load time/size for every page.

 


@Asjas wrote:

`$ is not defined` is a error that you can receive if the code that you are writing runs before jQuery is loaded. You haven't stated where jQuery is being declared in the HTML markup? If it is at the bottom of the html markup at the closing `body` tag then that is the problem. Because inline scripts will probably load before then.

 

You can move the jQuery script tag to the `head` tag to see if it fixes the issue.


 

0 Likes
New Member
23 0 0

Uh yeah - that's basically the problem. But testing if it exists doesn't help with running the code. I already know it doesn't exist yet / is not loaded because I'm getting the error that it isn't defined.


@Lonecrowlab wrote:

Most probably Jquery not yet loaded or not available. 
Try checking it in your console just copy paste that.

if (typeof jQuery == 'undefined') {
console.log("Jquery not available");
}
else{
console.log('Jquery Ver:' + jQuery.fn.jquery);
}

and Asjas is correct. Try putting it before the closing body tag. 


 

0 Likes
New Member
35 2 3

@fixyoursignin any chance you are using the Slate toolkit? I had some issues integrating jQuery into my theme when using this environment.

 

Otherwise, if you drop this in your theme.liquid right before the </head> tag, I'm thinking jQuery should be available in your site.

 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>

I'd be very interested to see the site if this didn't work. Got a link?

0 Likes
New Member
23 0 0

re: any chance you are using the Slate toolkit?

Not that I am aware of. We are customizing the default 'Debut' theme and only using a handful of shopify plugins.

 

SW

0 Likes
New Member
35 2 3

Another way you can include jQuery in your theme is inside assets/vendor.js -- simply copy and paste the latest minified jQuery version into this file, and make sure vendor.js is being loaded into your theme -- I think Debut has this inside theme.liquid <head> somewhere? 

 

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

 

0 Likes
New Member
23 0 0

re: another way to include jquery....

The problem does not seem to be including jquery. If I run jquery code from form events, it's loaded and works fine. If I add a setTimeout with a reasonably long-enough delay, the (delayed) onload script works fine. But if I just run immediately in the onload event, jquery isn't yet loaded.

Loading jquery is not the problem. jQuery is loading. Just not by the time the window onload handler executes. I need to know how people on shopify that want to run jquery based code after a page is loaded, do so.

0 Likes
Highlighted
New Member
23 0 0

(by the way, I've already addressed the immediate problem by removing all jQuery references in the code that I want executed after the page loads. i.e. I converted it all to direct DOM manipulation javascript based code. But I would still prefer to use jQuery tools in onload scripts in the future)

0 Likes