Show/Hide Submenu in wordpress - javascript

I know there's tons of pages dedicated to this on SO but my piece of code just doesn't seem to work. I keep getting a "Uncaught ReferenceError: $ is not defined". I've made use of jquery to show/hide my wordpress submenu when a user hover over the parent. (See code below)
Javascript
<script type="text/javascript">
$('.menu .nav li > .sub-menu').parent().hover(function() {
var submenu = $(this).children('.sub-menu');
if ( $(submenu).is(':hidden') ) {
$(submenu).slideDown(200);
} else {
$(submenu).slideUp(200);
}
});
HTML
<div id="masthead" class="menu navbar navbar" role="banner">
<div class="logo-navbar container-logo">
<div class="container-fullwidth">
<div class="navbar-header">
<div class="menu-left-container"><ul id="menu-left" class="nav navbar-nav"><li id="menu-item-184" class="menu-item">Item 1</li>
<li id="menu-item-239" class="menu-item"> Item 2
<ul class="sub-menu">
<li id="menu-item-238" class="menu-item">Sub-Item 1</li>
<li id="menu-item-237" class="menu-item">Sub-Item 2</li>
<li id="menu-item-240" class="menu-item">Sub-Item 3</li>
<li id="menu-item-241" class="menu-item">Sub-Item 4</li>
</ul>
</li>
</ul></div><a href="#" class="navbar-brand">
<img src="logo.png">
</a>
<div class="menu-right-container"><ul id="menu-right" class="nav navbar-nav"><li id="menu-item">Item 3 Illustrations</li>
<li id="menu-item-189" class="menu-item">Item 4</li>
</ul>
</div>
</div>
</div>
</div>
I guess im not referencing the right function. Hope somebody helps me out!
Cheers!

You need to make sure:
1.- You have included jQuery on the header/footer of your page.
2.- If you are using native jQuery from WordPress is defined as jQuery not as $.
3.- You should wrap your code inside of a $(document).ready function.
Example:
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('.menu .nav li > .sub-menu').parent().hover(function() {
var submenu = $(this).children('.sub-menu');
if ( $(submenu).is(':hidden') ) {
$(submenu).slideDown(200);
} else {
$(submenu).slideUp(200);
}
});
});
})( jQuery );
</script>
Reasons:
1.- You can test this on the chrome console by typing $ or jQuery in the console, and you should have and output like:
function (a,b){return new e.fn.init(a,b,h)}
2.- If you are using the jQuery included by WordPress you need to use jQuery instead of $ as mentioned before to avoid conflicts with other libs.
3.- Since otherwise the code is executed as soon as the document is ready if not your code can be executed before the DOM elements are on the document.

Are you importing jQuery properly? If not add this to the header.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
If that isn't the issue you can also try to see if adding $ = jQuery to the top of your script does the trick.

Related

jQuery dropdown toggle find active li and keep the dropdown open

I've got some trouble with a custom dropdown toggle.
The menu looks like this in HTML and I do not have the option to edit the code for that so I have to solve it with css/jQuery:
<ul>
<li>Link"</li> <-- when this is active it has class="active"
<li>Link"</li>
<li>Link"</li>
<li class=""> <-- this is always empty
<span>Title</span>
<ul>
<li class="active">Link</li> <-- this is currently active
<li>Link</li>
<li>Link</li>
</ul>
</li>
</ul>
I'm a bit afraid to ask but here is what I've got:
$('.menu li[class=""] span').click(function() {
const self = $(this).parent();
self.toggleClass("menu-open");
});
if($('.menu li[class=""]').find('li.active').length !== 0){
$(this).addClass("menu-open");
}
The first function which actually works pretty well checks if there is a li with a class="" as this indicates it has a submenu. Clicking the span in the li toggles the class menu-open which results in either having the menu open or collapsed.
Now I would like to keep the menu open when I'm on a page that's in the submenu. If that's the case the li in the sub ul is active, the parent li is not.
Unfortunately that doesn't work. I also tried different approaches such as hasClass, children but none of it worked either. I pinpointed the issue mostly to:
$(this).addClass("menu-open");
as it seems that $(this) was never found. If I change $(this) to $('body') for example and add a hide(), I clearly see that it works because I get a blank page :)
Any advise on what the issue is would be much appreciated as I nearly gave up now.
$(function() {
$('.menu li[class=""] span').click(function() {
const self = $(this).parent();
self.toggleClass("menu-open");
});
if($('.menu li[class=""]').find('li.active').length !== 0){
$(this).addClass("menu-open");
}
});
.menu{width:200px}
ul{list-style-type:none}
li{background:#ccc;margin:2px}
span{display:block}
.menu li[class=""]{
height:20px;
overflow:hidden;
cursor:pointer;
}
.menu-open{
height:auto;
overflow:visible;
cursor:pointer;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</head>
<body>
<div class="menu">
<ul>
<li>Link</li>
<li>Link</li>
<li>Link</li>
<li class="">
<span>Title</span>
<ul>
<li class="active">Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</li>
<li>Link<li>
<li>Link<li>
<li class="">
<span>Title</span>
<ul>
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
Try to use the each operator that JQuery provides.
It's something like this:
$('.menu li').each(function() {
if($(this).find('li.active').length !== 0) {
$(this).addClass('menu-open');
}
});
In your case, the context that is using the this expression doesn't represent the selector you tried to use in if.
in the example using each, the this expression that is inside the function represents the element being interacted represented by the selector.

jquery slidetoggle not working with div, ul, and display: none

I'm trying to toggle a menu dropdown with slideToggle but I can't seem to get it working. My goal is to click on "Attack" and have the list of attack options show. Here is my code.
<div class="turn-option" id="attack">
<h2>Attack</h2>
<div class="attack-menu">
<ul>
<li class="attack-type">Attack 1</li>
<li class="attack-type">Attack 2</li>
<li class="attack-type">Attack 3</li>
<li class="attack-type">Attack 4</li>
</ul>
</div>
</div>
.attack-menu {
display: none;
}
$(document).ready(function() {
$("#attack").click(function() {
$(".attack-menu").slideToggle("fast");
});
});
This works fine. Your jquery library might be causing the error. Try including this script :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
Refer this link : Example

I need help hiding an element when hovering over another non child/parent/sibling element

I'm a beginner when it comes to javascript and I'm trying to write a script to hide a class when I hover over another class. I've written this piece of code however it isn't working as I'd like it to.Could someone give me some pointers as to why this code isn't working and some advice on how to get it to achieve the results I'm looking for.
$(document).ready( function () {
"use strict";
document.getElementsByClassName('nav-bar').onmouseover = function(){
document.getElementsByClassName('site-title').style.display="none";
};
document.getElementsByClassName('nav-bar').onmouseout = function(){
document.getElementsByClassName('site-title').style.display="inline";
};
});
edit
#Jonas
$(document).ready( function () {
"use strict";
document.getElementsByClassName('nav-bar').forEach(function(el){el.onmouseover = function(){
document.getElementsByClassName('site-title').forEach(function(el){el.style.display="none";}
);
};
}
);
document.getElementsByClassName('nav-bar').forEach(function(el){el.onmouseout = function(){
document.getElementsByClassName('site-title').forEach(function(el){el.style.display="inline";});
};});
});
this is your adapted code. I'm not sure why it isn't working have i done it correctly?
edit 2
<body>
<Header>
<div class="navigation-wrap">
<div class="logo"><img src="../images/logo2.jpg" alt="Lewis Banks Logo" title="Lewis Banks & Sons Ltd"></div>
<div class="navigation">
<nav class="nav-menu">
<ul class="clearfix" >
<li class="nav-button"><a class="nav-bar" href="../index.html">Home</a></li>
<li class="nav-button">
<a id="product-button">Products</a>
<ul id="product-list">
<li class="menu-dropdown2"> AC
<ul id="AC-sublist">
<li class="dropdown-content"><a href="../CSW1-Switch.html">CSW1 Switch (15mm)<a>
</li>
<li class="dropdown-content"><a href="../CSW2-Switch.html">CSW2 Switch (20mm)<a>
</li>
<li class="dropdown-content"><a href="../CSW10-Switch.html">CSW10 Switch (30mm)<a>
</li>
</ul>
</li>
<li class="menu-dropdown2"><a href="../DC-Products.html" >DC</a>
<ul id="DC-sublist">
<li class="dropdown-content"><a href="../Cartridge-Brush-Holders.html">Cartridge Brush Holders<a>
</li>
<li class="dropdown-content">Brush Holder Caps
</li>
<li class="dropdown-content">Extruded Brush Holders
</li>
<li class="dropdown-content">Pressed Brass Brush Holders</li>
<li class="dropdown-content">Aluminium Brush Rockers
</li>
<li class="dropdown-content">Pressed Brass Brush Rockers</li>
<li class="dropdown-content">Tachometer Brush Rocker
</li>
<li class="dropdown-content">Carbon Brushes
</li>
<li class="dropdown-content">Constant Force Springs
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-button"><a class="nav-bar" href="../Applications.html">Applications</a></li>
<li class="nav-button"><a class="nav-bar" href="../Old-and-New.html">Old & New</a></li>
<li class="nav-button"><a class="nav-bar" href="../About-Us.html">About Us</a></li>
</ul>
</nav>
</div>
</div>
</Header>
<div class="site-title">
<h1>Lewis Banks & Sons</h1>
<h3><q>Labor Omnibus Unus</q></h3>
<h4><i>Company motto since 1916</i></h4>
</div>
</body>
This is my html code, I apologize in advanced for the confusing state it is in this is the first website i've ever tried to to make and I've had to do a lot of trial and error and other acts of desperation when i came unstuck.
I have a top menu bar which has submenu's. I managed to do that using CSS.
The problem i have is as i hover over the sub-menus they overlap with the site title which makes the page look ugly. I don't want to move the site titel down so instead i'd like to remove it whenever you hover over the initial menu buttons. I want to to do this whilst maintaining the page structre (ie there's whitespace where the tite was).
It seems you are using jQuery. Why not use jQuery selectors and methods to achieve your goal. It is easier to read and understand. Take a look at the following pages for more information:
http://api.jquery.com/on/
https://api.jquery.com/mouseover/
https://api.jquery.com/mouseout/
Try this for example:
$(document).ready( function () {
$(document).on('mouseover', '.nav-bar', function() {
jQuery('.site-title').css('display', 'none');
});
$(document).on('mouseout', '.nav-bar', function() {
jQuery('.site-title').css('display', 'inline-block');
});
});
GetElementsByClassName returns a HTMLCollection. You need to loopover, and add to each:
document.getElementsByClassName('nav-bar').forEach(function(el){el.onmouseover = function(){
document.getElementsByClassName('site-title').forEach(function(el){el.style.display="none";});
};});
Like Dais mentioned in his answer, it looks like you are using jQuery so why not use the built in jQuery mouse events. Either that or you copied your code from somewhere and didn't realize that $ is a shortcut for jQuery and for your javascript to work you need to include jQuery. To include jQuery you need a statment similar to below in your html. This will include jQuery from google's content delivery network (CDN). There are other CDN's available including ones directly from jQuery.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
https://api.jquery.com/category/events/mouse-events/
Below is a working example using jQuery events and selectors.
$(document).ready(function() {
"use strict";
$('#site-title').mouseover( function() {
$('#site-title').hide(500);
});
$('#nav-bar').mouseleave( function() {
$('#site-title').show(500);
});
});
#site-title {
position:absolute;
background:red;
width:100%;
height:50px;
}
#nav-bar {
position:absolute;
background:green;
width:100%;
height:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="nav-bar">I am the nav bar
<button>Nav1</button>
<button>Nav2</button>
<button>Nav3</button>
</nav>
<header id="site-title">I am the site title</header>

show third level ul menu with jquery

I have problems with creating a dropdown menu with jQuery.
This code shows the sub menus on hover but I couldn't get the sub sub menu to work too
$(document).ready(function() {
$("li").has(".sub").hover(function() {
$(this).find(".sub").toggle();
});
});
Here's the JS code
http://codepen.io/anon/pen/rVmabP
Lose the sub-sub class and use the immediate descendant selector to help you:
HTML
<ul id="nav">
<li>11111
<ul class="sub">
<li>2</li>
</ul>
</li>
<li>11111
<ul class="sub">
<li>2</li>
<li>22222
<ul class="sub">
<li>3</li>
</ul>
</li>
</ul>
</li>
</ul>
JavaScript
$(document).ready(function() {
$("li").has("> .sub").hover(function() {
$(this).find("> .sub").stop().slideToggle();
});
});
JSFiddle
Note that this would work for unlimited nested .subs.

jQuery slide down navigation

I'm trying to build a simple jQuery slide down navigation but I'm having a bit of a issue with toggle in on and off the navigation.
I have navigation as follows.
<ul id="nav">
<li>home</li>
<li class="parent">Clothing
<ul>
<li>child</li>
<li>child</li>
<li>child</li>
</ul>
</li>
<li class="parent">shoes
<ul>
<li>child</li>
<li>child</li>
<li>child
<ul>
<li>child child</li>
</ul>
</li>
</ul>
</li>
with the following jquery
var $j = jQuery.noConflict();
$j(document).ready(function() {
$j('#nav').children('.parent').click(function(e){
e.preventDefault();
$this = $j(this);
$j('#nav').children('.parent').children('ul').stop().slideUp('slow', function(){
$this.children('ul').stop().slideToggle('slow');
});
});
});
Now when i click the Sub navigation slides out, clicking again does nothing, and i need it to slide back up. If i click another one what I need to happen is have the expanded nav (if any) slide back up, and then the new one slide down after, but it's just not wanting to work correctly for me! It's buggy and both display at once, and sometimes don't show.
See this...
var $j = jQuery.noConflict();
$j(document).ready(function() {
$j('#nav > .parent').on('click', function(e){
e.preventDefault();
$j('#nav > .parent').children().stop().slideUp('slow');
$j(this).children().stop().slideToggle('slow');
});
});
See this jSfiddle example

Categories