Add Javascript to WordPress Menu

Is there a way to put javascript in the URL portion of a WordPress menu item? I have a live chat function on my site, and I am supposed to put this code onto the site to make a link to open the live chat (as suggested here).

<!-- BEGIN OLARK CHAT LINK -->
<a href="javascript:void(0);" onclick="olark('api.box.expand')">
    Click here to chat!
</a>
<!-- END OLARK CHAT LINK -->

The client wants the link in the utility nav bar, which was created used a WordPress menu in the WordPress dashboard. But when I copy and paste javascript:void(0);" onclick="olark('api.box.expand') into the URL box in the WordPress dashboard, it just disappears and the link remains inactive.

Something I read said that maybe I could put a custom class on the link in question and then write a Javascript function that fires when the link with that class is clicked. I tried that, though, and I couldn’t get it to work. I don’t know much Javascript, so it’s possible I was writing it entirely wrong.

Does anyone know how to do this? I would like to do it without using a plugin.

Solutions Collecting From Web of "Add Javascript to WordPress Menu"

Good that it works. If it’s for a client or if you just want a cleaner code, you can do it as @Tom J Nowell suggested.

Add a custom menu item, link it to nowhere or anywhere. Find out the menu item ID (every item has one), and then target that ID with jQuery.

$("#menu-item-num").on("click", function(e){ 
      e.preventDefault();
      // olark code here
});

This way, every time a user clicks on that menu-item the script above will be triggered. You can enqueue the jquery script via functions.php.

Update:

  1. Make sure your olark.js is loading. If you’re adding it to the footer or header, inspect your page and make sure the script is there. Also, make sure you’re not getting any errors in the browser’s console.

  2. Wrap your js with a document ready, so that the script executes at the right time:

    jQuery(document).ready(function($) {
      $("#menu-item-38872").on("click", function(e){
      e.preventDefault();
      olark('api.box.expand');
      });
    });
    

The fact that the link is not loading means there’s something wrong with the script itself or the script is not loading at all.

Solution #1 (not ideal, but it works):

// Live Chat Utility Link
add_filter( 'wp_nav_menu_items', 'live_chat_utility_link', 10, 2 );
function live_chat_utility_link ( $items, $args ) {
    if ( $args->theme_location == 'utility' ) {
        $items .= '<li><a href="javascript:void(0);" onclick="olark(\'api.box.expand\')" class="livechat">Live Chat</a></li>';
    }
    return $items;
}

Solution #2 (ideal):

With the help of the comments above, here is the solution that worked for me. I created a new file called olark.js and put this code in it:

jQuery(document).ready(function($) {
    $("#menu-item-38872").on("click", function(e){ 
          e.preventDefault();
          // olark code here
          olark('api.box.expand');
    });
});

Then, I enqueued the script in my functions.php with the following code:

function olark_script() {
    wp_register_script( 'olark', get_stylesheet_directory_uri() . '/js/olark.js', array(), '1.0.0', true );
    wp_enqueue_script( 'olark' );
}

add_action( 'wp_enqueue_scripts', 'olark_script' );

If it doesn’t work, make sure you are enqueuing your script properly. I am using a child theme, so I had to use get_stylesheet_directory_uri() instead of get_template_directory_uri().

I think there is a ‘more reliable’ option. Relying on the menu item number is not garanteed to work if you migrate your code from development to production for example. If you turn the number into a setting it is getting better, but still not really good.

An alternative could be to link to a non-existent anchor, like #olark, from your menu-item. This can be set using the user-interface and is reliable accross environments. Then your separate script should observe the hash-change (in the browser address bar) and act accordingly.

A simple coffee script example that compiles into javascript that listens to the hashchange:

if window.addEventListener
  window.addEventListener 'hashchange', (event) =>
  @showLogin()
else
  window.attachEvent 'onhashchange', (event) =>
  @showLogin()
#enable sharing the url
if location.hash then @showLogin()

@showLogin is a function that displays a dialog that let’s you login if the hash is equal to ‘#login’.

[edit]
Funny enough, the hash in the address does not change if you click a menu item. This is unexpected and could be due to another script preventing the default event. So I had to add another line, to make the window location change in response to clicking a link:

# make sure the hash changes when a link in the menu is clicked (somehow, it doesn't in my case)
$('.menu-item a').click (event) =>
  window.location = $(event.currentTarget).attr 'href'

[/edit]

You can use this to functions.php to add addition script in nav-menu item

function add_nav_class($output) {
$output= preg_replace('/<a/', '<a id="join_club" onclick="awf_Form_.showForm(); return false;"', $output, -1);
return $output;
}
add_filter('wp_nav_menu', 'add_nav_class');