2

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:

Menu With the Script

Without the script running:

Menu Without the Script

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;
    }
}
  • "Late execution" is what I read. Imagine it's true. And there is no reason to paste JavaScript here when it's not a part of WordPress. – Max Yudin Feb 10 '18 at 23:19
  • @MaxYudin I understand, but the question is not about the JS code at all, it's about how WordPress handles that code. – Jonathan Guerin Feb 11 '18 at 1:31
  • If so, remove JavaScript from the question to make it clean, simple and free of clutter. You'll get more chances to be read and answered. – Max Yudin Feb 11 '18 at 6:14
  • @MaxYudin Great feedback, analyzed and implemented. – Jonathan Guerin Feb 11 '18 at 12:16
0

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.

| improve this answer | |
  • Aye! The script is called within the footer. Any examples on some code on how I could use a child theme to do this? – Jonathan Guerin Feb 11 '18 at 2:30
  • Sure. this link provides everything you need to know about creating a child theme, which won't take longer than 2 minutes. – Jack Johansson Feb 11 '18 at 2:31
0

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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.