adding extra identifiers to dom elements - javascript

I have a bunch of menu items in a list format like so
<ul class="menu unselectable">
<li class="group">
Group Title
<ul>
<li class="groupItem i0">item 0</li>
<li class="groupItem i1 over">item 1</li>
</ul>
</li>
<li class="group">
Another Group Title
<ul>
<li class="groupItem i2">item 2</li>
<li class="groupItem i1">item 1 (if I hover here, the others should too</li>
</ul>
</li>
</ul>
The idea is, if I hover on one item with class i1 then all i1 items should behave the same. So I thought of adding a class over to all i1 items when I hover on any of them like so.
$(".groupItem").hover(
function () {
$(this).addClass("over");
},
function () {
$(this).removeClass("over");
}
);
The problem is I can't think of a way to identify what item has just been hovered on aside from $(this). To remedy this I thought of adding i1 as an id to items, but different dom nodes shouldn't have the same id. My next idea was to add the attribute value to the li items but to no avail (when I did a quick test with $(this).val() kept returning 0 regardless of the value actually stored in the node.
Is there any way I can add an identifier so I can just say $(this).<someIdentifier> , and target all the dom nodes with that identifier?

you can add an attribute groupID="{id}" and then call $(this).attr('groupID')

Element.prototype.secondId = '';
and than
document.getElementById('id5').secondId = 13;
As this you just set on any element a new property which you can use as you wish but is just in javascript not in html.

I don't recommend adding false attributes to elements, and this will work even if data attributes are not well supported by the user's browser:
$(".groupItem").hover(
function () {
var className = this.className.split(' ')[1];
$('.' + className).addClass("over");
},
function () {
var className = this.className.split(' ')[1];
$('.' + className).removeClass("over");
}
);
NOTE: Requires that classes are always organized as you specified above. A safer way could be:
var className = $.trim(this.className.replace('groupItem',''));

$(this).filter('#selector')

Please, Try working below code as below once:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
<style>
.menu{ display:inline;}
.menu li{ display:inline; float: left;width: 100px;}
.menu li ul{display:none;}
</style>
<script type="text/javascript">
$(document).ready(function(){
$(".group").hover(
function () {
$(this).find("ul").show();
},
function () {
$(this).find("ul").hide();
}
);
});
</script>
</head>
<body>
<ul class="menu">
<li class="group">
Group Title
<ul>
<li>GT 1</li>
<li>GT 2</li>
</ul>
</li>
<li class="group">
Trochlear Nerve
<ul>
<li>TN 1</li>
<li>TN 2</li>
</ul>
</li>
</ul>
</body>
</html>

Related

Adding item to html list with JS when there is no ID

I'm working on a script to add some extra features to a menu. The current user-menu is a drop-down list with links such as My profile, My reports, etc. I'm looking to add another item, "My posts".
I'm having a couple of difficulties due to the way the site is working.
This is the code for the drop down:
<li class="user expandable">
*list items*
</li>
I'm using document.getElementById to pick up elements but have no idea how to pick up the list and add an item to it. I believe there are other element pickers such as class but they didn't seem to work either.
Adding item to html list with JS when there is no ID
To get the first found item document.querySelector then use a css selector for example document.querySelector('div') to find the first div or document.querySelector('.user') to find the first element with class user
to get every item that matches document.querySelectorAll which will return an array of all the items matched.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
const list = document.querySelector('.user.expandable');
function addMyNewRow(message, index = 0) {
const node = document.createElement('li');
node.innerHTML = message
list.insertBefore(node, list.childNodes[index]);
}
function addChild() {
addMyNewRow('clicked and added in first');
}
addMyNewRow("added in second", 2)
<ul class="user expandable">
<li>old list item</li>
<li>old list item</li>
<li>old list item</li>
<li>old list item</li>
</ul>
<button onclick="addChild()">add list </button>
I think this is something similar to what you're looking for:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#btn2").click(function(){
$(".user").append("<li>Appended item</li>");
});
});
</script>
</head>
<body>
<ol class="user expandable">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ol>
<button id="btn2">Append list item</button>
</body>
</html>
$( "li" ).hover(
function() {
$( this ).append( $( hfhfhfha ) );
}
);
"this" keyword gives you the reference you need.

Adding event listeners to multiple elements with JavaScript

What I am trying to do is target all the a tags within #menu-wrap li's.
I'm fairly new to JS so I'm sorry if I'm missing something obvious!
JavaScript:
var menuLink = document.querySelector( '#menu-wrap li' );
for (var i = 0; i < menuLink.children.length; i++) {
var childElement = menuLink.children[i];
childElement.addEventListener('click', doSomething, false);
}
function doSomething() {
alert("Hello");
}
HTML
<div class="menu-wrap" id="menu-wrap">
<nav class="menu">
<ul id="menu-mobile-menu" class="menu">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 1</li>
</ul>
</nav>
</div>
querySelector:
Returns the first element within the document (using depth-first pre-order traversal of the document's nodes|by first element in document markup and iterating through sequential nodes by order of amount of child nodes) that matches the specified group of selectors.
You want to use querySelectorAll and then loop over the resulting node list (or you want to bind your event handler to #menu-wrap itself and then use event.target to determine which list item was clicked on).
List items are not designed to be interactive controls. You should use a link or button instead.
Document.querySelector gets the first element only. But you can do this with classes. Do this. Just attatch class sth to anything you want to have the function.
HTML
<div class="menu-wrap" id="menu-wrap">
<nav class="menu">
<ul id="menu-mobile-menu" class="menu">
<li class="sth">Link 1</li>
<li class="sth">Link 2</li>
<li class="sth">Link 1</li>
</ul>
</nav>
</div>
JS
var menuLink = document.getElementsByClassName("sth");
for(var i = 0; i < menuLink.length; i++ ) {
var childElement = menuLink[i];
childElement.addEventListener('click', doSomething, false);
}
function doSomething() {
alert("Hello");
}

Jquery If class has matching ID then hide

What I'm trying to do here is check if an element has the same id as a class in another element if so hide the matching id.
So far this is what I have came up with but it doesn't seem to kick.
JSfiddle
var theid = $('#me li').attr('id');
if ($('#you li').hasClass( theid )) {
$('#me li#'+theid+'').hide();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<ul id="me">
<li id="num-0">iam 1</li>
<li id="num-1">ieam 2 & should be hidden</li>
<li id="num-2">iam 3</li>
<li id="num-3">iam 4</li>
<li id="num-4">ieam 5 & should be hidden</li>
<li id="num-5">iam 6</li>
</ul>
<ul id="you">
<li class="num-1">iam killer</li>
<li class="num-4">iam killer</li>
</ul>
Use each() to loop over all the li elements inside the #you
hide() the elements having the id same as the class of current element in loop.
$('#you li').each(function() {
$('#' + $(this).attr('class')).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<ul id="me">
<li id="num-0">iam 1</li>
<li id="num-1">ieam 2</li>
<li id="num-2">iam 3 & should be hidden</li>
<li id="num-3">iam 4</li>
<li id="num-4">ieam 5 & should be hidden</li>
<li id="num-5">iam 6</li>
</ul>
<ul id="you">
<li class="num-2">iam killer</li>
<li class="num-4">iam killer</li>
</ul>
Demo
When you use the .attr() method on a jQuery object that contains multiple elements, it just returns the attribute from the first element. You need to loop over each element and check them one at a time.
It is, however, OK for your purposes to use .hasClass() on the set of all of the #you elements, because .hasClass() will return true if any of the elements in the set has that class. So:
var you = $('#you li');
$('#me li').each(function() {
if (you.hasClass(this.id))
$(this).hide();
});
Note that I'm keeping a reference to the $('#you li') jQuery object in the variable you to save selecting those elements again every time in the loop.
Demo: https://jsfiddle.net/d65sz4js/2/
Try this for your jquery:
$(function() {
$("#you li").each(function(){
var theid = $(this).attr('class');
$('#'+theid).hide();
});
});
Demo: https://jsfiddle.net/nkem9o7o/
You could filter the #me li's, returning elements where their id exists as a class in #you li's, then just hide them. This would also work for multiple classes:
$('#me li').filter(function() {
return $('#you').has('.' + this.id).length;
}).hide();
Here's a fiddle

get list equal height inside div element

Please take a look at this FIDDLE. I have two pairs of unordered lists, each of which is inside a div element.pricing-table. The following code can find the li with the same classes, get the max height and set the height of all of them to the same. But I want to limit it to getting the max-height of each pair of lists inside each div element.
I think this line is giving me problem because it is getting all the lists with the same classes in the document:
var elems = $('.pricing-table ul li.' + elem.className),
I don't think I can use $(this) and update it like $(this +elem.className). Any suggestions?
Jquery script:
$(document).ready( function(){
$('.pricing-table ul li').each(function(i, elem) {
var elems = $('.pricing-table ul li.' + elem.className),
heights = $.map(elems, function(li) {
return $(li).height();
}),
max = Math.max.apply(null, heights);
elems.height(max);
});
});
HTML
<div class="pricing-table">
<ul>
<li class="heading">Bronze</li>
<li class="year">2003<p>(Text)..........</li>
<li class="package">Starter package</li>
<li class="location">Africa (Text).......)</li>
<li class="description">Text............ </li>
</ul>
<ul class="feature">
<li class="heading">Silver</li>
<li class="year">2004</li>
<li class="package">Intermediate package</li>
<li class="location">Asia</li>
<li class="description">Text............ </li>
</ul>
</div>
<div class="pricing-table">
<ul>
<li class="heading">Bronze</li>
<li class="year">2003<p>(Text)..........</li>
<li class="package">Starter package</li>
<li class="location">Africa (Text).......)</li>
<li class="description">Text............ </li>
</ul>
<ul class="feature">
<li class="heading">Silver</li>
<li class="year">2004</li>
<li class="package">Intermediate package</li>
<li class="location">Asia</li>
<li class="description">Text............ </li>
</ul>
</div>
You’d need to get only the li that are descendants of your current .pricing-table element, so you’ll have to iterate over the latter first:
$(document).ready(function () {
$('.pricing-table').each(function (i, e) {
$(e).find('ul li').each(function (i, elem) {
var elems = $(e).find('ul li.' + elem.className),
heights = $.map(elems, function (li) {
return $(li).height();
}),
max = Math.max.apply(null, heights);
elems.height(max);
});
});
});
… or something like that. http://jsfiddle.net/p3sfy/3867/
(Still kinda ugly, since it will iterate over the li multiple times, so that’s rather just a “quick fix” – but I don’t wanna think about anything more sophisticated here before I have not first heard a convincing argument why this data is not marked up using tables in the first place …?)

Set DIV to visible when hyperlink hover - CSS/HTML

I have attached a snippet of my HTML.
Is it possible if I hover over the hyperlink with ID li1link that div#li1 is displayed, and if I hover over the hyperlink with ID li2link then div#li2 is displayed. Is this easily achievable?
So I guess the default is the DIVs are set to display:hidden until that particular related link is hovered over/active.
To confirm, only one DIV will be visible at any time.
Here is my current HTML:
<ul>
<li>Test 1 - hover over to display ul#li1</li>
<li>Test 2 - hover over to display ul#li2</li>
</ul>
<div id="li1">
<ul>
<li>Content 1</li>
<li>Content 1</li>
</ul>
</div>
<div id="li2">
<ul>
<li>Content 2</li>
<li>Content 2</li>
</ul>
</div>
I'm open to using jQuery or CSS, I'm just not totally sure how to approach this issue. Confused is an understatement.
Many thanks for any pointers with this.
You could try:
// for all links that have link keyword in their ids
$('a[id*="link"]').mouseenter(function(){
// get the div id out of this
var id = this.id.replace('link', '');
// hide all other divs
$('div[id^="li"]').hide();
// show the needed div now
$('#' + id).show();
});
// hide when mouse moves away
$('a[id*="link"]').mouseout(function(){
var id = this.id.replace('link', '');
$('#' + id).hide();
});
To confirm, only one DIV will be visible at any time.
These lines take care of that:
$('div[id^="li"]').hide();
// show the needed div now
$('#' + id).show();
$("#li1link).hover(function(){
$("#li1").attr('display','block');
});
$("#li1link).mouseover(function(){
$("#li").attr('display','none');
});
You can do similar thing when #li2link and display #li2 and hide it.
try this:
<!DOCTYPE html>
<html>
<head>
<script>
var p = {
onmouseover: function(link) {
document.getElementById(link.id.substring(0, 3)).style.display = "block";
},
onmouseout: function(link) {
document.getElementById(link.id.substring(0, 3)).style.display = "none";
}
};
</script>
</head>
<body>
<ul>
<li>Test 1 - hover over to display ul#li1</li>
<li>Test 2 - hover over to display ul#li2</li>
</ul>
<div id="li1" style="display: none;">
<ul>
<li>Content 1</li>
<li>Content 1</li>
</ul>
</div>
<div id="li2" style="display: none;">
<ul>
<li>Content 2</li>
<li>Content 2</li>
</ul>
</div>
</body>
</html>
You can check it here
CSS:
#li1link, #li2link {
display: none;
}​
jQuery:
$("#li1, #li2").hover(
function () {
$('#' + $(this).attr('id') + 'link').show();
},
function () {
$('#' + $(this).attr('id') + 'link').hide();
});​
With a minor html change (adding a class to your ul) you can handle it all in 1 function,
Assumption: The a->href value and the div ID are same.
DEMO
HTML Change:
<ul class="showDivOnHover">
<li>Test 1 - hover over to display ul#li1</li>
<li>Test 2 - hover over to display ul#li2</li>
</ul>
JS:
$('.showDivOnHover a').hover (function() {
$($(this).attr('href')).show();
}, function () {
$($(this).attr('href')).hide();
});
I used jQuery, tried to give you a quick solution:
http://jsfiddle.net/88nKd/
<ul id="nav">
<li>Test 1 - hover over to display ul#li1</li>
<li>Test 2 - hover over to display ul#li2</li>
</ul>
<div id="li1" class="none">
<ul>
<li>Content 1</li>
<li>Content 1</li>
</ul>
</div>
<div id="li2" class="none">
<ul>
<li>Content 2</li>
<li>Content 2</li>
</ul>
</div>
css:
.none{
display:none;
}
js:
$(document).ready(function(){
$(".liLink").mouseover(function(){
var linkNumber = $(this).attr('id');
var divNumber = '#li'+linkNumber;
$(divNumber).show();
}).mouseout(function(){
var linkNumber = $(this).attr('id');
var divNumber = '#li'+linkNumber;
$(divNumber).hide();
});
});
Cheers!
I find having a class which deals with the styles and then adding and removing those works well for me, so:
(Please note the below code will remove the class when not hovering over the link and I would recommend giving the links sensible class names to do the selector on rather than all a tags, same with the divs)
CSS:
div {
visibility:hidden; // Or display:none; or left: -999em; depending on what your page is there for.
}
div.show {
visibility: visible;
}
JS:
$('a').hover(function() {
$($(this).attr('href')).addClass('show');
}, function() {
$($(this).attr('href')).removeClass('show');
});

Categories