Run code when HTML is ready

I want to run this snippet of code:

 if( $(window).width() < 979 ){
        $(".main-navigation.navigation-top-header").remove();
        $(".toggle-navigation").css("display","inline-block");
 }

When all the HTML has loaded. I tried onRendered, onCreated, startup, $(document).ready() but nothing works.

The classes are not loaded yet (Body tag is empty), so nothing is changed. How do I run code when HTML is ready?

I think onRendered should work. I am surprised it doesn’t.

3 Likes

Why would you not do something like this by using CSS media queries?

@media(max-width: 978px) {
  .main-navigation.navigation-top-header { display: none; }
  .toggle-navigation { display: inline-block; }
}

(MQ syntax may be off, it’s been a few months since I last had to write them manually.)


But to also answer your question:

You’re on track with what you suggested and tried, so it’s likely that the problem is somewhere else, like either something loading and executing async, or a bug / false expectation somewhere in your (other, not shown) code.

1 Like

What’s the template structure? It looks like you are resizing a navbar (which I agree with @seeekr that media queries feels more natural a solution). Maybe you should use a template for the body content and have its onRendered() tweak the navbar

1 Like

I think you might be onto something @jasoncchild . I pushed everything to Git https://github.com/servermeta/motter-contact

I will arrive at office in 30 and comment further, thank you all guys for your help.

Tracker.afterFlush is your friend. It will execute code only after all Blaze templates on the page (and any reactive data) has fully rendered.

3 Likes

According the Core API documentation, with Meteor.startup():

On a server, the function will run as soon as the server process is finished starting. On a client, the function will run as soon as the DOM is ready.

The startup callbacks are called in the same order as the calls to Meteor.startup were made.

On a client, startup callbacks from packages will be called first, followed by templates from your .html files, followed by your application code.

Meteor.startup is called just once after the DOM is ready, and will not be called again (on the client side) until a complete page reload. That may or may not be what @muaddib wants to accomplish, not sure.

I cloned the repo and added

Template.mainLayout.onRendered(function() { mobileNavigation(); });

and the code gets executed…at least the css classes get added/removed and whatnot…however when looking at it in the inspector i see nested <body> tag sets.

EDIT:
I totally realize now that you have the body tags defined within your mainLayout template. moving the tags to the outside of the template declaration fixes the double tags as your templates are being injected into the body.

1 Like

You are totally right, but there might not even need for that. I’m porting a commercial theme (spotter) to meteor. It has been 3 painful months.

At first I bought it as soon as it came out. It had some Sass errors which fucked everything up. I had to learn SASS (1 wasted month), and then fix the CSS. At the beginning the author refused to admit there was any error in the Sass. One week after I fixed the CSS, he published a new version with fixed Sass. First flip table rage quit.

When I was sure CSS was working, I switched to port JS. Let’s take this example. There is one case if width is less than 979. Then another snippet does the same exact thing if width is greater that 979. But in a very convoluted way.

JS code is really messy, many things seems useless, it is poorly documented, and if you touch something then something else will break. For example mobile styles are loaded in desktop version, and vice versa. It’s a nightmare.

I’m studying line for line to understand what’s happening, how code interact with the rest, etc. I will definitely rewrite most of it, but I need to learn it first/.

Thanks that did it.

Thank you very much @jasoncchild . I’ve made several forks of the main repo with CSS working, because I want to play with the JS code. I missed that.

Anyhow I have another problem now: Some pages relies on body tags to correctly show CSS. Different pages have different body tags. If I put body tags outside of template, then they will be loaded by default.

How can I specify body tags on a per template basis?

anyhow this is very funny. Quoting @miningsam

it is the hacker way – learn your game by pulling out your last hairs

I didn’t have this much fun since doing physics in college :smile:

1 Like

Sadly I think instead of trying the have multiple body tags (which off hand
I can’t think of a way to pull off) you will need to refactor the css to
apply to something like an outer div wrapper.

I once spent a dark and stormy night with a bootstrap template from xyz
template mill, a 5th of scotch and a gallon of discontent trying to wrangle
a mess of crap, similar to what you describe.

My face and palm haven’t been quite so often together since that night…

1 Like

You cant mess with body tag in the index page directly, but you can change it using package.

Inject.rawModHtml('changingBody', function(html) {
    return html.replace(/<body>/, '<body class="whatever you want" >');
});
1 Like