onfocus event on a link - javascript

I am building a menu that is driven by CSS and I have come across a problem for keyboard users. There is no cross browser support for the CSS :focus selector, so I am trying to build a jQuery script that will perform the same action.
HTML menu:
<div id="nav">
<ul>
<li>Home</li>
<li>About Us</li>
<li>What We Do
<ul>
<li>What we do1</li>
<li>What we do2</li>
</ul>
</li>
<li>Test Studies</li>
</ul>
</div>
CSS rules for menu:
#nav ul {
padding: 0; margin: 0;
}
#nav ul li {
list-style: none;
font-size: 16px;
}
#nav ul li ul li {
font-size: 13px;
}
#nav ul li ul {
display: none;
}
.showMenu, #nav ul li:hover ul{width:200px; padding:7px; background: #F2F2F2; border:1px solid #F2F2F2; display: block; position: absolute; left: 85px; top: 30px; }
Here is the jQuery code that I am trying to get to work:
$(document).ready(function(){
$('#whatWeDo').focus(function() {
$(#nav ul li ul).addClass("showMenu");
});
});

you forgot quotes:
$(document).ready(function(){
    $('#whatWeDo').focus(function() {
           $('#nav ul li ul').addClass("showMenu");
      });
 });

You have forgotten quotes, the jQuery should be:
$(document).ready(function(){
$('#whatWeDo').focus(function() {
$('#nav ul li ul').addClass("showMenu");
});

Like noted in other answers, surrounding your innermost selector with quotes should do the trick.
Though, I'd like to further point out that it is recommended to bind events using the on() function, which was added in jQuery 1.7. Here's how your code would look using on():
$(document).ready(function(){
$("#whatWeDo").on("focus", function() {
$("#nav ul li ul").addClass("showMenu");
});
});
Here is more info about on().

Related

Create click off event on animated navigation dropdown

I have 2 problems:
I'm trying to create an click-off event, where a click off of the "nav" menu is detected, which triggers the deselection of the open list element and retracts its respective dropdown content.
My current code doesn't allow another list element/navigation item without dropdown content to be added, as doing so hinders the entirety of the code from working. I'd like to add another "nav" list element that doesn't have dropdown contents, without hindering the functionality of the other list elements and their respective dropdown content.
Here is my code (also available on JSFiddle):
$(function() {
function animate() {
$('#nav .nav-ul li').off('click', animate)
var $detected = $(this).closest('.nav-ul');
$detected.find('li.detected').removeClass('detected');
$(this).addClass('detected');
//figure out which rel to show
var ulToShow = $(this).attr('rel');
//hide current rel
if ($('.substitute .sub-child.active').length > 0) {
$('.substitute .sub-child.active').hide(700, function() {
$(this).removeClass('active');
$('#' + ulToShow).fadeIn(528, function() {
$(this).addClass('active');
$('#nav .nav-ul li').on('click', animate)
});
});
} else {
$('#' + ulToShow).fadeIn(528, function() {
$(this).addClass('active');
$('#nav .nav-ul li').on('click', animate)
});
}
}
$('#nav .nav-ul li').on('click', animate);
});
* {
margin: 0;
padding: 0;
}
#nav {
background-color: /*blue*/
;
float: right;
}
#nav .nav-ul {
list-style: none;
float: right;
background-color: /*yellow*/
;
border-left: solid 2px #000000;
border-right: solid 2px #000000;
}
#nav .nav-ul li {
float: left;
padding: 4px;
font-weight: bold;
color: #000000;
}
#nav .nav-ul li:hover {
cursor: pointer;
text-decoration: underline;
color: #E51D27;
}
#nav .nav-ul li.detected {
color: #E51D27;
}
#nav .substitute {
float: right;
background-color: /*pink*/
;
margin-right: 4px;
}
#nav .substitute .sub-child {
float: left;
display: none;
}
#nav .substitute .sub-child.active {
display: block;
}
#nav .substitute .sub-child ul {
list-style: none;
}
#nav .substitute .sub-child ul li {
float: left;
padding: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="nav">
<ul class="nav-ul">
<li class="" rel="pay1">Color</li>
<li rel="pay2">Shape</li>
<li rel="pay3">Size</li>
</ul>
<div class="substitute">
<div id="pay1" class="sub-child">
<ul>
<li>Red</li>
<li>Blue</li>
<li>Green</li>
</ul>
</div>
<div id="pay2" class="sub-child">
<ul>
<li>Square</li>
<li>Circle</li>
<li>Triangle</li>
<li>Diamond</li>
</ul>
</div>
<div id="pay3" class="sub-child">
<ul>
<li>Small</li>
<li>Medium</li>
<li>Large</li>
</ul>
</div>
</div>
</div>
I'm trying to create an click-off event, where a click off of the "nav" menu is detected, which triggers the deselection of the open list element and retracts its respective dropdown content.
For this you could create a click event handler on the body that closes the menu if it's open. Something like this:
// close menu when clicking anywhere on the document
$(document).on("click", function() {
$("#nav li.detected").removeClass("detected");
$("#nav div.active").hide(700, function() { $(this).removeClass("active"); });
});
Then to avoid it from closing when you click on the menu, you can use .stopPropagation() in the animate function to stop the bubbling of the events up the DOM tree when clicking on it.
My current code doesn't allow another list element/navigation item without dropdown content to be added, as doing so hinders the entirety of the code from working. I'd like to add another "nav" list element that doesn't have dropdown contents, without hindering the functionality of the other list elements and their respective dropdown content.
This happens because you are associating and disassociating events every time that you click on the menu (something that is not really necessary), so when one of the navigation items doesn't have a dropdown associated to it, the event handler is removed (with the off() in the animate function) but it is not associated again, which causes this behavior that you don't want.
The solution is simple: there's no apparent need to be detaching and re-attaching the click event handlers every time that the animate function is called. Remove the call to off and on within the animate function and that would be it.
Here you can see both changes applied to your code:
$(function() {
function animate(e) {
e.stopPropagation();
var $detected = $(this).closest('.nav-ul');
if (!$detected.hasClass("active-animation")) {
$detected.addClass("active-animation");
$detected.find('li.detected').removeClass('detected');
$(this).addClass('detected');
//figure out which rel to show
var ulToShow = $(this).attr('rel');
//hide current rel
if ($('.substitute .sub-child.active').length > 0) {
$('.substitute .sub-child.active').hide(700, function() {
$(this).removeClass('active');
$('#' + ulToShow).fadeIn(528, function() {
$(this).addClass('active');
$detected.removeClass("active-animation");
});
});
} else {
$('#' + ulToShow).fadeIn(528, function() {
$(this).addClass('active');
$detected.removeClass("active-animation");
});
}
}
}
$('#nav .nav-ul li').on('click', animate);
// close menu when clicking anywhere on the page
$(document).on("click", function() {
$("#nav li.detected").removeClass("detected");
$("#nav div.active").hide(700, function() {
$(this).removeClass("active");
});
});
});
* {
margin: 0;
padding: 0;
}
#nav {
background-color: /*blue*/
;
float: right;
}
#nav .nav-ul {
list-style: none;
float: right;
background-color: /*yellow*/
;
border-left: solid 2px #000000;
border-right: solid 2px #000000;
}
#nav .nav-ul li {
float: left;
padding: 4px;
font-weight: bold;
color: #000000;
}
#nav .nav-ul li:hover {
cursor: pointer;
text-decoration: underline;
color: #E51D27;
}
#nav .nav-ul li.detected {
color: #E51D27;
}
#nav .substitute {
float: right;
background-color: /*pink*/
;
margin-right: 4px;
}
#nav .substitute .sub-child {
float: left;
display: none;
}
#nav .substitute .sub-child.active {
display: block;
}
#nav .substitute .sub-child ul {
list-style: none;
}
#nav .substitute .sub-child ul li {
float: left;
padding: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="nav">
<ul class="nav-ul">
<li class="" rel="pay1">Color</li>
<li rel="pay2">Shape</li>
<li rel="pay3">Size</li>
<li>No Dropdown</li>
</ul>
<div class="substitute">
<div id="pay1" class="sub-child">
<ul>
<li>Red</li>
<li>Blue</li>
<li>Green</li>
</ul>
</div>
<div id="pay2" class="sub-child">
<ul>
<li>Square</li>
<li>Circle</li>
<li>Triangle</li>
<li>Diamond</li>
</ul>
</div>
<div id="pay3" class="sub-child">
<ul>
<li>Small</li>
<li>Medium</li>
<li>Large</li>
</ul>
</div>
</div>
</div>

Change the active navbar color in css

I am using a simple top css navbar(just a css and html, without bootstrap/other framework) and i would like to change the active page. So when i go to the home page, the button color in navbar changes into red/whatever, likewise when i go to the other page...
here the code:
body {
margin: 0;
}
.logo {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f2f2f2;
float: left;
width: 25%;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 40px;
text-decoration: none;
font-size: 18px;
}
li a:hover {
background-color: #111;
}
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>
do you have an idea? it's ok to add javascript
Thanks a lot!
What I did here is when $(document).ready(function() {..} get the path using var url = window.location.pathname; so you know which link the user coming from therefore you know which menu item they clicked.
Then $('ul li a').each(function() {...} will check each menu item, try to match the url path with the menu's href attributes, if a match found, make that menu item active (with css active class added), if not match remove the active class if any. That should do the trick.
(note: assume your app is not single page app)
for Single page app it is much easier, deactive all menu item then active the one you clicked.
$(document).ready(function() {
//var url = window.location.pathname;
var url = 'http://stacksnippets.net/js#division';
console.log('url-->', url);
$('ul li a').each(function() {
var href = $(this).attr('href');
if (!!url.match(href)) {
$(this).addClass('active');
} else {
$(this).removeClass('active');
}
});
});
body {
margin: 0;
}
.logo {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f2f2f2;
float: left;
width: 25%;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 40px;
text-decoration: none;
font-size: 18px;
}
li a:hover {
background-color: #111;
}
.active {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>
The simplest solution would be to add an active class to the link of the page you're on:
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>
Then style those that class accordingly:
li a.active {
background: #F00;
}
If you're using a CMS (Wordpress, etc), adding some sort of active class on the active link is usually done for you. If you're doing your own static HTML, you would have to do it manually.
try below code for active menu
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('li a').on('click', function(){
$('li a').removeClass('active');
$(this).addClass('active');
});
});
</script>
<style type="text/css">
body {
margin: 0;
}
.logo {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f2f2f2;
float: left;
width: 25%;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 40px;
text-decoration: none;
font-size: 18px;
}
li a:hover, li a.active {
background-color: #111;
}
</style>
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>
To change the color of active link in your navigation you need to do the following things:
On click of navigation link add css class:
$('ul li a').click(function(){
$('li a').removeClass("active");
$(this).addClass("active");
});
Add CSS for active class
ul li a.active {
background-color: #f4f4f4;
}
One possible way is to use the active selector in CSS. This selector highlights the active element you are using when its clicked.
a:active {
background-color: yellow;
}
a:focus {
background-color: yellow;
}
You can use some JQuery to turn it on and off too. Try looking at this post here, I think you may have get your answer.
(Related to How to keep :active css style after clicking an element)
jQuery('button').click(function(){
jQuery(this).toggleClass('active');
});
function redButtons() {
$(".inclusive-buttons").on("click", "a", function() {
$(".inclusive-buttons a").css("background", "#333");
$(this).css("background", "red");
})
}
var x = document.getElementsByTagName("li");
x.onclick = redButtons();
body {
margin: 0;
}
.logo {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f2f2f2;
float: left;
width: 25%;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 40px;
text-decoration: none;
font-size: 18px;
}
li a:hover {
background-color: #111;
}
a:active {
background-color: red;
}
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<ul class="inclusive-buttons">
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>
https://jsfiddle.net/m5gm7x7e/2/
HTML Part
<div class="navbar">
<div class="navbar-fixed-top">
<div class="container" style="width: auto;">
<div class="nav-collapse" id="nav-collapse">
<ul class="nav" id="nav">
<li id="News">News</li>
<li id="Contact">Contact</li>
<li id="About">About</li>
<li id="Division">Division</li>
<li id="Career">Career</li>
<li id="skill">Skill</li>
<li id="research">Research</li>
<li id="MChoice">MChoice's</li>
</ul>
</div>
</div>
</div>
</div>
JavaScript part
$(function() {
$('#nav li a').click(function() {
$('#nav li').removeClass();
$($(this).attr('href')).addClass('active');
});
});
CSS Part
.navbar #nav > .active > a {
color: yellow;
}
here is JSFiddle result
http://jsfiddle.net/Ag47D/775/
Here's a JSFiddle: https://jsfiddle.net/timhjellum/nw3n7eka/103/
This is a jQuery option which looks at the page URL (window.location) and specifically for a string which you define in the .indexOf(" add a unique string here ") and asks if that string is greater than -1, then locate the li element with the class you assigned to it, and add another class called active.
In the example I'm using "display" because that the URL for that iFrame that JSFiddle uses so hopefully that's not confusing.
Here's the navigation:
$(document).ready(function () {
if(window.location.href.indexOf("home") > -1) {
$(".home").addClass("active");
}
if(window.location.href.indexOf("display") > -1) {
$(".news").addClass("active");
}
//make one for each nav element
});
The HTML needs to be modified like:
<ul>
<li class="home">Home</li>
<li class="news">News</li>
<li class="contact">Contact</li>
<li class="about">About</li>
</ul>
And then a simple css addition:
li.active {
background-color: white;
}
li.active a {
color: black;
}
If you can't use jQuery, let me know but this is the easiest solution for you to implement and allow you to easily modify
You could try having separate classes in your CSS file, like "ul-home," "ul-news," etc. and define different background colors for each, then simply set the class for your <ul> tag on each page to match the class you want. So:
.ul-home {
background-color: red;
}
.ul-news {
backrgound-color: yellow;
}
And then on your home page:
<ul class="ul-home>
<li>Home</li>
<li>News</li>
</ul>
On your news page:
<ul class="ul-news">
<li>Home</li>
<li>News</li>
</ul>
Etc. with all the other pages you have.

convert CSS Hover to JS onClick for Dropdown Menu?

I want to create a simple dropdown menu when a user clicks on an image. Currently I'm using CSS hover but it doesn't stay so I want to convert it to a JS onClick function.
<html>
<head>
<style>
ul {
text-align: left;
display: inline;
margin: 0;
list-style: none;
}
ul li {
display: inline-block;
position: relative;
}
ul li ul {
padding: 0;
position: absolute;
display: none;
opacity: 0;
visibility: hidden;
}
ul li ul li {
display: block;
}
ul li:hover ul {
display: block;
opacity: 1;
visibility: visible;
}
</style></head><body>
<ul>
<li>
<img src="https://cdn1.iconfinder.com/data/icons/thincons/100/menu-128.png" width="20px;" height="18px;"/>
<ul class="lang">
<li>Web Design</li>
<li>Web Development</li>
<li>Illustrations</li>
</ul>
</li>
</ul>
</body>
</html>
With a little jQuery, we can easily toggle a class on or off to represent 'showing' the menu:
$("#menu").click(function(){
$(this).toggleClass("activated");
});
And changing the CSS (instead of :hover) to:
ul li.activated ul {
display: block;
opacity: 1;
visibility: visible;
}
The HTML only needs that first li element to have an id, which lets us use jQuery to bind a click event to it.
<ul>
<li id="menu">
You can see it all in action on this fiddle.
Edit: For a non-jQuery solution, you can use the following Javascript code:
var myEl = document.getElementById('menu');
myEl.addEventListener('click', function() {
this.classList.toggle('activated');
}, false);

Nav bar mouseenter/mouseleave not working between li elements

I'mm trying to design a specific type of navbar in javascript/jquery.
I cannot get mouseenter() and mouseleave() to work correctly when the mouse passes between the li objects.
Here is my code. Any ideas?
http://jsfiddle.net/richofwombwell/1v8L0pdz/38/
function inversebuttonon(liId, aId) {
$(liId).css('background-color', 'white');
$(aId).css('background-color', 'white');
$(aId).css('color', '#0086CA');
}
function inversebuttonoff(liId, aId) {
$(liId).css('background-color', '#0086CA');
$(aId).css('background-color', '#0086CA');
$(aId).css('color', 'white');
}
function showselectedmenu(liclass, aclass) {
$('.menu').css('max-height', '100px');
$(liclass).css('display', 'inline');
$(aclass).css('display', 'inline');
}
function dontshowselectedmenu(liclass, aclass) {
$('.menu').css('max-height', '0px', 'none');
$(liclass).css('display', 'none');
$(aclass).css('display', 'none');
}
$('#n-2').mouseenter(function () {
inversebuttonon('#n-2', '#a2');
showselectedmenu('.tmenuli', '.tmenua1');
});
$('.menu').mouseleave(function () {
dontshowselectedmenu('.tmenuli', '.tmenua1');
inversebuttonoff('#n-2', '#a2');
});
$('#n-3').mouseenter(function () {
inversebuttonon('#n-3', '#a3');
showselectedmenu('.tmenuli2', '.tmenua2');
});
$('.menu').mouseleave(function () {
dontshowselectedmenu('.tmenuli2', '.tmenua2');
inversebuttonoff('#n-3', '#a3');
});
Your script does not work correctly because your html code is invalid (you are nesting DIVs instead of list elements. That forces the browser to correct your code (the way it wants to).
Before you continue scripting, please consider using CSS solution:
* {
box-sizing: border-box;
font-family: sans-serif;
font-size: 16px;
}
.my_menu {
height: 66px;
text-align: center;
width: 100%;
overflow:
}
.my_menu ul {
list-style: none;
}
.my_menu ul li {
display: inline-block;
}
.my_menu > ul {
position: relative;
background: none #0086CA;
}
.my_menu ul a {
text-decoration: none;
color: #fff;
display: inline-block;
}
.my_menu > ul > li > a {
padding: 15px 20px;
}
.my_menu > ul > li > a:hover,
.my_menu > ul > li a:focus {
color: #0086CA;
background: #fff;
}
.my_menu ul ul {
background: none grey;
position: absolute;
top: 100%;
left: 0;
right: 0;
width: 100%;
display: none;
}
.my_menu ul li:hover ul {
display: block;
}
.my_menu ul ul a {
padding: 5px 10px;
}
.my_menu ul ul a:hover,
.my_menu ul ul a:focus {
background: none black;
}
<header>
<nav class="my_menu">
<ul>
<li>
Home
</li>
<li>
menuitem1
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
</li>
<li>
menuitem2
<ul>
<li>item5</li>
<li>item6</li>
<li>item7</li>
<li>item8</li>
</ul>
</li>
</ul>
</nav>
</header>
Also at Playground.
You can probably clean this up but if you insist on a script method, this will work: It also should be easier to extend with less id's etc. just add markup.
Working example here: http://jsfiddle.net/MarkSchultheiss/fLqs1nru/2/
function showmenu(targ, me) {
$('.menuitem').removeClass('menu-on');
$(me).parent().addClass('menu-on');
$('.menu').hide();
$('.' + targ).show();
}
$('.menuitem a').mouseenter(function () {
var targ = $(this).parent().data("targetmenu");
showmenu(targ, this);
});
$('nav').mouseleave(function () {
$('.menuitem ').removeClass('menu-on');
$('.menu').hide();
});
Adjust the markup, get rid of the div and add some classes. Add a data element for the target menu to use.
<nav>
<ul class="ulparent">
<li class="navitem" id="n-1">Home
<li class="navitem menuitem" data-targetmenu="menu1">menuitem1
</li>
<li class="navitem menuitem" data-targetmenu="menu2"><a href="#" >menuitem2</a>
</li>
<ul class="menu menu1">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
<ul class="menu menu2">
<li>item5</li>
<li>item6</li>
<li>item7</li>
<li>item8</li>
</ul>
</ul>
</nav>
add this to the end of you CSS (which can probably be cleaner but this is only additive:)
.menu-on {
background-color: white;
}
.menu-on a {
color:#0086CA;
}
.menu {
max-height:100px;
display:none;
}

Vertical menu css3

I am stuck on the creation of a vertical menu with submenu:
<ul>
<li>Home</li>
<li>Pages
<ul>
<li>Subpage</li>
<li>Subpage 2</li>
</ul>
</li>
<li>Contact</li>
</ul>
Clicking on "Pages" the menu should be something similar to this:
The basic mechanic can be achieved like this:
ul li ul {
display: none;
margin-left: 20px;
}
li:hover ul {
display: block;
}
jsFiddle: http://jsfiddle.net/elias94xx/sCXus/
Without the use of images it's somewhat tricky to achieve the effect in your images above, but I got a decent example working:
jsFiddle: http://jsfiddle.net/elias94xx/sCXus/5/
Try This
use this CSS:
ul{
list-style:none;
}
ul li ul{
list-style:none;
display:none;
}
apply jQuery library and this function:
$(document).ready(function(){
$("ul li").click(function(){
$(this).children('ul').show();
});
});

Categories