How can I make sure my JS script gets executed first, among other scripts?

I have this script that cuts down my menu and adds a "+" dropdown if there are too many menu items in an attempt to prettify long menus, as such:

Without the script running:

Which I call in functions.php with:

function _s_scripts() {
    wp_enqueue_script( 'main', get_template_directory_uri() . '/js/main_res.js', array( 'jquery' ), '', false );
}
add_action( 'wp_enqueue_scripts', '_s_scripts' );

Unfortunately, this results in late-execution and jagginess. Is there any way I can hook this script into "as soon as you're done generating X part (menu)" do this?

The effect is very noticeable for the user:

https://imgur.com/aoFcYKe

and here's the script, just for testing purposes, main_res.js:

function sliceMenu(desired_len) {
    var menu_len = document.querySelectorAll('#primary-menu  li').length;

    if (menu_len  desired_len) {

        var append_menu_el = document.createElement('div');
        append_menu_el.innerHTML = ('div id="js-cover-menu"img class="plus" src="$PATH/svg/plus_menu.svg" alt="more-menu"/div').replace('$PATH', ABSPATH);
        document.getElementById('primary-menu').parentNode.appendChild(append_menu_el);

        let diff = menu_len - desired_len;
        let sliced_lis = [...(document.querySelectorAll('#primary-menu  li'))].slice(-diff);


        var js_menu_el = document.createElement('ul');
        js_menu_el.setAttribute('id', 'js-cover-menu-dropdown');
        document.getElementById('js-cover-menu').appendChild(js_menu_el);

        js_cover_menu_el = document.getElementById('js-cover-menu-dropdown');

        for(var i = 0, length = sliced_lis.length; i  length; i++) {
            js_cover_menu_el.appendChild(sliced_lis[i]);
        }
        document.querySelectorAll('#js-cover-menu-dropdown  li  ul').forEach(node = node.remove());
    } else {
        return;
    }
}

Topic wp-enqueue-script Wordpress

Category Web


It looks like your script is partially using vanilla javascript. If you can get rid of its dependence on jQuery then you can just stick it right into a script tag in your footer.

However, scripts that are run on $( document ).ready() will always have this effect if you are changing the html of the page.

Your 2 solutions are: write the script properly in php, by setting up the hidden items with CSS classes so they don't show on page load, and use javascript logic to add click handlers to the "+".

Another slightly more hacky option, is to hide the div with CSS, and at the end of your javascript, apply a CSS class that shows it. Now the page will load with nothing, and a split second later, the menu will become visible. This is a bit better than the menu loading looking one way, and then changing completely after the page loads.


First of all, if you are not using jQuery, then do not pass the jQuery as a dependency to the wp_enqueue_script() function.

Now, about your question. It's not really WordPress related, but anyway. You didn't mention how you call this function, since that's all that matters here. If you output your code lately, such as in the footer, it won't run until everything before that part is loaded. My suggestion is, to use a child them and add the code directly after your menu is output, and call the function. This way, the script will run immediately after the menu is created, and since no jQuery is required, you won't have a problem using it.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.