Attach event handler to every li - javascript

I have this code and I want to attach DIFFERENT event handlers to every <a> without using id or class.
I tried this but didn't work...
$('#points ul li a').on('click', function(event) {
// I don't know why this selectors doesn't work
if ($(event.target).is(':eq(0)')) {
alert('0') // and do something
}
if ($(event.target).is(':eq(1)')) {
alert('1') // and do something
}
if ($(event.target).is(':eq(2)')) {
alert('2') // and do something
}
})
#points ul {
list-style: none;
font-size: 5em;
padding: 0;
margin: 0;
line-height: .5em;
}
#points ul li {
float: left;
}
#points ul li a {
text-decoration: none;
color: grey;
padding: .1em;
line-height: .1em
}
#points {
position: relative;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="points">
<ul>
<li>.
</li>
<li>.
</li>
<li>.
</li>
</ul>
</div>
<script
Thanks in advance.

As suggested there are many alternate solutions, but the specific
error in your code was regarding your usage of :eq(0). Change it to #points>ul>li>a:eq(0) as per the jQuery documentation .
REPLACE
if ($(event.target).is(':eq(1)')) {
WITH
if ($(event.target).is('#points>ul>li>a:eq(0)')) {
Note: I have used #points>ul>li>a so that other <a> tags above and below are not selected. ( in light of your comment regarding the same )
I want to just add that if I was asked to do the same I'd take an
approach like:
var objArr = $('#points>ul>li>a');
objArr.on('click', function(event) {
switch($(objArr).index(this)){
case 0:
alert('0');
break;
case 1:
alert('1');
break;
case 2:
alert('2');
break;
}
});
That said your method works too and the WORKING EXAMPLE with the error I mentioned above adjusted for:
$('#points>ul>li>a').on('click', function(event) {
// I don't know why this selectors doesn't work
if ($(event.target).is('#points>ul>li>a:eq(0)')) {
alert('0') // and do something
}
if ($(event.target).is('#points>ul>li>a:eq(1)')) {
alert('1') // and do something
}
if ($(event.target).is('#points>ul>li>a:eq(2)')) {
alert('2') // and do something
}
})
#points>ul {
list-style: none;
font-size: 5em;
padding: 0;
margin: 0;
line-height: .5em;
}
#points>ul>li {
float: left;
}
#points>ul>li>a {
text-decoration: none;
color: grey;
margin: .1em;
}
#points>ul>li>a {
background-color: yellow;
}
div {
margin-bottom: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
random link
random link
random link
</div>
<br />
<div id="points">
<ul>
<li>.
</li>
<li>.
</li>
<li>.
</li>
</ul>
</div>
<br />
<br />
<br />
<div>
random link
random link
</div>

Include a selector before :eq()
$('#points ul li a').on('click', function(event) {
var el = $(event.target);
if (el.is('a:eq(0)')) {
alert('0') // and do something
}
if (el.is('a:eq(1)')) {
alert('1') // and do something
}
if (el.is('a:eq(2)')) {
alert('2') // and do something
}
})
#points ul {
list-style: none;
font-size: 5em;
padding: 0;
margin: 0;
line-height: .5em;
}
#points ul li {
float: left;
}
#points ul li a {
text-decoration: none;
color: grey;
padding: .1em;
line-height: .1em
}
#points {
position: relative;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="points">
<ul>
<li>.
</li>
<li>.
</li>
<li>.
</li>
</ul>
</div>
<script

Try this
var items = $('#points li a');
$('#points ul li a').on('click', function(event) {
var currentItem = event.currentTarget
if (items.index(currentItem) === 0) {
alert('0') ;
}
if (items.index(currentItem) === 1) {
alert('1') ;
}
if (items.index(currentItem) === 2) {
alert('2');
}
})
#points ul {
list-style: none;
font-size: 5em;
padding: 0;
margin: 0;
line-height: .5em;
}
#points ul li {
float: left;
}
#points ul li a {
text-decoration: none;
color: grey;
padding: .1em;
line-height: .1em
}
#points {
position: relative;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="points">
<ul>
<li>.
</li>
<li>.
</li>
<li>.
</li>
</ul>
</div>

Related

How to convert toggle function to module pattern in javascript?

I'm a new javascript, i have heard that declaring global variables it's pretty much bad idea in javascript, we have to less or avoid as much as we can.
I have found page https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals and i saw module pattern it seems a good way to go.
So, i've been practicing about toggle function my first code it works fine
function toggle() {
var mainTopics = document.querySelector("#maintopics"); // target the li
mainTopics.addEventListener("click", function (e) { // passed "e" to get the event
e.preventDefault(); // prevent anchor to navigate
mainTopics.classList.toggle("show"); // changed to toggle for the
// the purpose of this demo
});
}
toggle();
body {
margin: 0;
}
li, a{
text-decoration: none;
list-style-type: none;
text-decoration-line: none;
color: black;
}
/*main-menu*/
#mainmenu {
position: relative;
}
#mainmenu ul {
margin: 0;
padding: 0;
}
#mainmenu li {
display: inline-block;
}
#mainmenu a {
display: block;
width: 100px;
padding: 10px;
border: 1px solid;
text-align: center;
}
/*sub-topics*/
#subtopics {
position: absolute;
display: none;
margin-top: 10px;
width: 100%;
left: 0;
}
#maintopics.show #subtopics {
display: block;
}
#subtopics ul {
margin: 0;
padding: 0;
}
#subtopics li {
display: block;
}
#subTopics a {
text-align: left;
}
/*columns*/
#column1, #column2, #column3 {
position: relative;
float: left;
left: 125px;
margin: 0px 5px 0px 0px;
}
/*hover underline*/
#mainmenu li:hover {
text-decoration: underline;
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="index2.css" />
</head>
<body>
<div id="mainmenu">
<ul>
<li>Logo</li>
<li>Home</li>
<li id="maintopics">Topics
<div id="subtopics">
<div id="column1" class="columns">
<ul>
<li>example1</li>
<li>example2</li>
<li>example3</li>
</ul>
</div>
</div>
</li>
</ul>
</div>
<script src="index2.js"></script>
</body>
</html>
I changed code javascript to module pattern.However it didn't work, im not sure if my code is wrong or there is some important rule that i don't know.
If anyone would like to give me some advices i will appreciate it thank you very much.
var toggle = (function() {
var mainTopics = document.getElementById("maintopics");
mainTopics.addEventListener("click", function(e) {
e.preventDefault();
mainTopics.classList.toggle("show");
});
return {
toggle()
}
})();
Hi, everyone i suddenly found the solution for my case. i just need to specific the function that i want to return to object again for example in my case return toggle function it would be toggle: toggle()
var toggle = (function () {
var mainTopics = document.getElementById("maintopics");
mainTopics.addEventListener("click", function (e) {
e.preventDefault();
mainTopics.classList.toggle("show");
});
return {
toggle: toggle()
}
})();

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.

How to insert text anchor inside attributes onclick?

I have a jquery tab and it's working fine.
Fiddle here
$(document).ready(function() {
$('.nnntabs ul a').on('click', function(e) {
var current = $(this).attr('href');
$('.tab-content > div' + current).fadeIn('slow').show().siblings().hide();
$(this).parent('li').addClass('active').siblings().removeClass('active');
e.preventDefault();
});
});
I just wanted to add more feature. The text anchor should be dynamically inserted inside the href and id attributes to activate the tab, or maybe replaced if there is a default value... The source of the value of href and id will be the text anchor of the menu. My fiddle sample is working fine because I inserted the values manually. Please help me turn this into reality... Thank you.
I think what you are looking for is
$(document).ready(function() {
var $content = $('.nnntabs > .tab-content > div');
$('.nnntabs > ul a').each(function(i) {
$(this).data('tab', 'tab-' + i);
$content.eq(i).attr('id', 'tab-' + i)
})
$('.nnntabs ul a').on('click', function(e) {
var current = $(this).data('tab');
$('#' + current).fadeIn('slow').show().siblings().hide();
$(this).parent('li').addClass('active').siblings().removeClass('active');
e.preventDefault();
});
});
.nnntabs {
width: 100%;
}
.nnntabs ul {
width: 100%;
margin: 0;
padding: 0;
}
.nnntabs ul li {
display: inline-block;
list-style: none;
border: 1px solid #ddd;
border-bottom: 0
}
.nnntabs ul li a {
padding: 8px 10px;
display: block;
font-size: 1em;
font-weight: bold;
color: #4c4c4c;
background: #eee;
}
.nnntabs ul li.active > a {
background: #fff;
color: #4c4c4c;
margin-bottom: -1px;
padding-bottom: 9px;
}
.tab-content {
padding: 10px;
border: 1px solid #ddd;
}
.tab-content > div {
display: none;
}
.tab-content > .active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="nnntabs">
<ul>
<li class="active">tab1</li>
<li>tab2</li>
<li>tab3</li>
</ul>
<div class="tab-content">
<div class="active">
content1
</div>
<div>
content2
</div>
<div>
cotent3
</div>
</div>
</div>

Adding 3rd level to CSS menu

I am using very old portal where the is not defined in the begining of the html code, and also I managed to use a jquery/css horizontal drop menu, I need help adding third level to the menu here is my code
#jsddm {
margin: 0;
padding: 0
}
#jsddm li {
float: left;
list-style: none;
font: 12px Tahoma, Arial
}
#jsddm li a {
display: block;
background: #324143;
padding: 5px 12px;
text-decoration: none;
border-right: 1px solid white;
width: 70px;
color: #EAFFED;
white-space: nowrap
}
#jsddm li a:hover {
background: #24313C
}
#jsddm li ul {
margin: 0;
padding: 0;
position: absolute;
visibility: hidden;
border-top: 1px solid white
}
#jsddm li ul li {
float: none;
display: inline
}
#jsddm li ul li a {
width: auto;
background: #A9C251;
color: #24313C
}
#jsddm li ul li a:hover {
background: #8EA344
}
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
var timeout = 500;
var closetimer = 0;
var ddmenuitem = 0;
function jsddm_open()
{ jsddm_canceltimer();
jsddm_close();
ddmenuitem = $(this).find('ul').eq(0).css('visibility', 'visible');}
function jsddm_close()
{ if(ddmenuitem) ddmenuitem.css('visibility', 'hidden');}
function jsddm_timer()
{ closetimer = window.setTimeout(jsddm_close, timeout);}
function jsddm_canceltimer()
{ if(closetimer)
{ window.clearTimeout(closetimer);
closetimer = null;}}
$(document).ready(function()
{ $('#jsddm > li').bind('mouseover', jsddm_open);
$('#jsddm > li').bind('mouseout', jsddm_timer);});
document.onclick = jsddm_close;
</script>
and here is the menu
<ul id="jsddm">
<li>About us
<ul>
<li>Mission
<ul>
<li>Mission Statment 1</li>
</ul>
</li>
<li> vision </li>
<li>status </li>
</ul>
</li>
<li> Contact
<ul>
<li>Office </li>
<li> Support </li>
</ul>
</li>
</ul>
as you can see the 3rd level "Mession Statment 1" doesn't appear, and that's my problem, any suggestion ???
The problem is maybe due to these lines
$('#jsddm > li').bind('mouseover', jsddm_open);
$('#jsddm > li').bind('mouseout', jsddm_timer);
in which you set an event handler only to the direct <li> children of #jsddm element. But your third <ul> is not contained in a such <li>, so try to change the above lines in
$('#jsddm li').bind('mouseover', jsddm_open);
$('#jsddm li').bind('mouseout', jsddm_timer);
and
function jsddm_open() {
...
ddmenuitem = $(this).children('ul:first').css('visibility', 'visible');}

Fitting a <ul>'s width to accommodate the menu items

I have a menu that contains submenus. Its HTML source looks like this:
<ul id="menu">
<li>
Menu 1
<ul>
<li><a href="javascript:;">Item 1<a></li>
<li>
Subitem 1
<ul>
<li>Subsubitem 1</li>
</ul>
</li>
</ul>
</li>
</ul>
After applying some CSS and getting the JavaScript side of things in order with Superfish, the menu looks like this in the browser:
The second menu item is too big to fit into its space, so the remainder of the text is rendered onto the text of the next menu item. Is there a way to enlarge the <ul> to make sure that the text fits?
Update: here's the relevant CSS code:
ul#menu {
position: relative;
top: 160px;
left: 130px;
width: 700px;
}
ul#menu, ul#menu ul {
list-style-type: none;
}
ul#menu > li {
display: block;
float: left;
background: url(img/menuitem.png) top left;
width: 104px;
height: 37px;
margin-right: 5px;
text-align: center;
}
ul#menu > li:hover {
background-position: bottom left;
}
ul#menu > li > a {
height: 100%;
padding-top: 10px;
font-size: 80%;
font-weight: bold;
color: white;
}
ul#menu > li > a, ul#menu > li > ul a {
display: block;
text-decoration: none;
}
ul#menu > li ul {
min-width: 150px;
}
ul#menu > li > ul li {
color: black;
font-size: 10pt;
text-align: left;
padding-left: 5px;
padding-right: 5px;
height: 30px;
line-height: 30px;
background: url(img/menubg.png) repeat;
}
ul#menu > li > ul li:hover {
background-color: #9c938c;
}
ul#menu > li > ul a {
color: black;
}
ul#menu > li ul {
position: relative;
top: -10px;
}
ul#menu > li li.hoverItem > ul {
position: relative;
top: -30px;
}
ul#menu > li > a > span.sf-sub-indicator {
display: none;
}
ul#menu > li > ul > li a > span.sf-sub-indicator {
float: right;
margin-right: 5px;
}
span.sf-sub-indicator and li.hoverItem are used by Superfish. sf-sub-indicator is used to indicate that hovering over a menu item will cause a submenu to be opened like so:
<li>
Menu item with submenu<span class="sf-sub-indicator"> ยป</span>
<ul>
<!-- Etc -->
</ul>
</li>
li.hoverItem is applied to all menu items you passed to get to the menu where your mouse is positioned, plus the menu item your mouse is currently hovering on.
Ok, I put something together using the same css definitions that you posted above. This works for me - automatically detects the size of the largest element and adjusts the related CSS.
You'll need to adjust the li elements to have a predictable naming scheme, so that it can find the largest one. Depending on your font, you might need to adjust the *5 portion of the assignment for the newSize.
<html>
<head>
<title></title>
<meta content="">
<script type="text/javascript">
function changeSize() {
var html = document.getElementById("item"+1).innerHTML;
var newSize = html.length*5;
var num_menu_items = 3;
for (i=2; i<=num_menu_items; i++) {
var temp = document.getElementById("item"+i).innerHTML;
if (temp.length > newSize / 5)
newSize = temp.length*5;
}
var theRules = new Array();
var rule;
if (document.styleSheets[0].cssRules)
theRules = document.styleSheets[0].cssRules
else if (document.styleSheets[0].rules)
theRules = document.styleSheets[0].rules
for (i = 0; i<theRules.length; i++) {
if (theRules[i].selectorText.indexOf("ul#menu > li ul") > -1) {
rule = theRules[i];
}
}
rule.style.setProperty('min-width',newSize+"px",null);
}
</script>
</head>
<body onload='changeSize();'>
<ul id="menu">
<li>A-one</li>
<li>A-two</li>
<li>A-three
<ul>
<li id='item1'>B-one</li>
<li id='item2'>B-two-is-really-really-really-really-really-really-really-really-really-really-really-really long</li>
<li id='item3'>B-three</li>
</ul>
</li>
</ul>
</body>
</html>
This block here:
ul#menu > li ul {
min-width: 150px;
}
Is where the size for that item is. You will have to change that to something larger.
The reason it doesn't expand, is because its parent's width is small than that.

Categories