Show next sibling element if is previous element hovered with pure JavaScript - javascript

I have this snippet of html
ul { display:none }
test 1
test 2
test 3
<ul class="hh-ul-1 mm-listitem">
sub 1
</ul>
Test 4
<ul class="hh-ul-1 mm-listitem">
sub 2
</ul>
By default ul elements are hidden.
I'm trying to achieve when the a element is hovered to show only ul element which is the next sibling.
For example, if test 3 link has hovered, the ul element with sub 1 link needs to show up and to stay while the a and ul are hovered.
I'm not so experienced, so any help would be appreciated.

Have a look at adjacent sibling combinator
I add focus so you can keep the UL open
Also the a in the UL should be in an li. That makes it somewhat harder to make a sub-sub menu
ul { display:none; position: absolute; top:50px }
a:hover + ul { display: block }
a:focus + ul { display: block }
test 1
test 2
test 3
<ul class="hh-ul-1 mm-listitem">
<li>sub 1</li>
</ul>
Test 4
<ul class="hh-ul-1 mm-listitem">
<li>sub 2</li>
</ul>

Related

Add class to current and previous list items

I have an unordered list used as a menu to play sections of a video. The list item (video portion) that's playing highlights when clicked by adding a class to it and removing the class from any other list item. I've been asked by the client to change this so that if you click on an item, the previous list items are selected also. Namely if you click on Vid 2, then Vid 1 and Start are given the 'selected' class as well as Vid 2. Clicking on Vid 3, would highlight Vid 3, Vid 2, Vid 1, Start and so on.
I would also like to remove the selected class from any list item that's ahead of the clicked item. For instance if Vid 4 is selected and the user clicks on Vid 2, then the selected class is removed from Vid 4 and Vid 2, Vid 1 and Start have the class selected. Sorry if any of this makes little sense and thanks in advance.
$("#select li a").click(function() {
$(this).parent().addClass('selected').siblings().removeClass('selected');
});
#video-controls ul li {
cursor: pointer;
}
#video-controls ul li a {
color: #5f6a72;
text-decoration: none;
display: block;
}
#video-controls ul li.selected,
#video-controls ul li.selected a {
color: #00aad2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<nav id="video-controls">
<ul id="select">
<li id="start">Start</li>
<li id="vid-1">Vid 1</li>
<li id="vid-2">Vid 2</li>
<li id="vid-3">Vid 3</li>
<li id="vid-4">Vid 4</li>
</ul>
</nav>
You can
1) traverse and get all previous elements.
2) use .andSelf() to add clicked object parent
3) add class selected to all elements returned above.
4) find remaining siblings other than returned element in step 2
5) remove class selected
$("#select li a").click(function() {
$(this).parent().prevAll().andSelf().addClass('selected').filter(':last').nextAll().removeClass('selected');
});
#video-controls ul li {
cursor: pointer;
}
#video-controls ul li a {
color: #5f6a72;
text-decoration: none;
display: block;
}
#video-controls ul li.selected,
#video-controls ul li.selected a {
color: #00aad2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<nav id="video-controls">
<ul id="select">
<li id="start">Start</li>
<li id="vid-1">Vid 1</li>
<li id="vid-2">Vid 2</li>
<li id="vid-3">Vid 3</li>
<li id="vid-4">Vid 4</li>
</ul>
</nav>

Multiple dropdown navigation - how to change the trigger button

I am struggling with one of my dropdowns.
Currently it is set up to be triggered by an i tag to drop down the sub menu.
$('nav li i').click(function() {
I want to change it to (nav li a) so it is not the icon that has to be pressed
I also have the code:
var child = $(this).index('nav ul li i');
but i am not sure what to change this to?
You can see all the code in jsfiddle.
http://jsfiddle.net/susannalarsen/VNYAx/
Since I do not see the <a> element anywhere, I have changed the <i> to <a> for demonstration purposes. You can see the example on http://jsfiddle.net/VNYAx/3/
Basically I changed
$('nav li i').click(function() {
to
$('nav li a').click(function() {
And also
var child = $(this).index('nav ul li i');
to
var child = $(this).index('nav ul li a');
Is this what you need?
Instead of using the index of the icon as a way to identify which dropdown you want to slide down, you can save a reference to that dropdown by searching for '.dropdown' within the element clicked.
$('nav li').click(function () {
var $childDropdown = $(this).find('.dropdown');
if ($childDropdown.is(':visible')) {
$('.dropdown').slideUp(300);
} else {
$('.dropdown').slideUp(300);
$childDropdown.slideDown(300);
}
});
http://jsfiddle.net/9Fk7j/2/
Just an alternative approach to this problem using .slideToggle(). If you need anything explaining please comment and I will edit the answer. I have commented the JavaScript below. I also removed the extra <div> in the markup as the nested <ul> is a perfectly good container.
Demo
HTML
<nav id="moo">
<ul>
<li>Item A
<ul>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</li>
<li>Item B
<ul>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
</ul>
</li>
</ul>
</nav>
CSS
ul {
padding: 0;
margin: 0;
}
li {
display: inline;
}
nav li {
position: relative;
}
ul ul {
display: none;
position: absolute;
border:1px solid #ccc;
padding: 10px;
}
ul ul li {
display: block;
}
JavaScript
var $allSubMenus = $('ul ul'); // handle to all submenus
$('nav li a').click(function (e) {
var $li = $(this).closest('li'); // get parent <li> of the <a> clicked on
var $subMenu = $li.find('ul'); // get our submenu
$allSubMenus.not($subMenu).slideUp(300); // hide all other submenus
$subMenu.slideToggle(300); // show our submenu
e.stopPropagation(); // stop event bubbling further
});
$(document).click(function () {
$allSubMenus.hide(); // no need to reselect, just use handle
});

Activate dropdown with pure javascript

Right now I have a pure HTML CSS navigation bar with some dropdowns. However on ipad the hover will obviously not work.
I want to add a click event to the relevant menu items so the dropdown will also activate with an onclick event.
I've look at other answers but I'm not capable of reading javascript well enough so that I can modify them for my specific site.
here is a link to where I'm at now: http://2ftrade.nl/kareem/eindopdracht/
and this is the relevant html. In my css the default is display:none for the dropdown menus and is changed to display:block when hovered over the li that contains it.
<ul>
<li>Home</li>
<li><a title="">Opleiding</a>
<!-- the dropdown -->
<ul>
<li>Visie & Beleid</li>
<li>Opbouw Studieprogramma</li>
<li>Competenties</li>
<li>Diploma</li>
<li>Beroepen</li>
</ul>
</li>
<li>Onderwijsprogramma</li>
<li>Organisatie</li>
<li><a title="">Stages en Projecten</a>
<!-- another dropdown -->
<ul>
<li>Stages</li>
<li>Projecten</li>
</ul>
</li>
<li>Top</li>
</ul>
This is the css that hides the dropdown section
nav > ul > li > ul {
display: none;
position: absolute;
}
and this is what will display it when hovering
nav > ul > li:hover ul {
display: block;
}
you can attach event listener to your element:
var dropdown_button = document.getElementById('#your-button-that-activates-dropdown');
dropdown_button.addEventListener('click', function() {
//here do what you want to do when the button is clicked.
}, false);
you should use javascript events , some thing like this :
var btn = document.getElementById('btn') // this button is a key to run what you want
var drp = document.getElementById('drp') // this is your dropdown list
btn.onclick = function()
{
drp.style.display = 'block'
// other codes . . .
}
You can achieve this without using javascript.
Use the :target selector
example
Add an id and href for each target in the html
<ul>
<li>Home</li>
<li id="Opleiding">
<a title="" href="#Opleiding">Opleiding</a>
<!-- the dropdown -->
<ul>
<li>Visie & Beleid</li>
<li>Opbouw Studieprogramma</li>
<li>Competenties</li>
<li>Diploma</li>
<li>Beroepen</li>
</ul>
</li>
<li>Onderwijsprogramma</li>
<li>Organisatie</li>
<li id="StagesenProjecten">
Stages en Projecten
<!-- another dropdown -->
<ul>
<li>Stages</li>
<li>Projecten</li>
</ul>
</li>
<li>Top</li>
</ul>
in the css specify the style for the :target
nav > ul > li:target ul {
display: block;
}
nav > ul > li:hover ul {
display: block;
}
nav > ul > li > ul {
display: none;
position: absolute;
}

How to make sub links appear when mouse upon a link

I have placed my code in http://jsfiddle.net/ChvjL/4/
While the mouse pointer is upon Link1 then the sub links link1a, link1b, link1c should appear.
Similarly for Link2 also.
Can anyone help me in resolving this
Thanks in advance
Amith
Here is an idea how it should be in your case:
html
<ul>
<li>Link1
<ul>
<li>Link1a</li>
<li>Link1b</li>
<li>Link1c</li>
</ul>
</li>
<li>Link2
<ul>
<li>Link2a</li>
<li>Link2b</li>
<li>Link2c</li>
</ul>
</li>
</ul>
Css
ul > li { width:100px; float:left; }
ul > li > ul { display:none; }
ul > li:hover > ul { display:block; }
ul > li > ul { padding-left:10px; }
Code http://jsfiddle.net/ChvjL/10/
Are you trying to say that when a person hovers at the link given, another link will be shown?
You can refer to this example. It's similar. You just need change the content:
http://www.dynamicdrive.com/style/csslibrary/item/css-image-gallery/

Show headers only for collections that are not empty

I have a couple of lists like this:
<ul>
<li class="list-header">Header</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
By some rules I hide and show <li> items so sometimes the list has visible <li> and sometimes it has no visible <li> elements at all except the one with list-header class, so <li class="list-header"> is still there. I want to hide that header if there are no <li> visible elements in it under header. Though I want the <ul> still to be visible.
How do I do that?
What you could do (demo):
$('ul').each(function() {
$ul = $(this);
$ul.find('.list-header').toggle($ul.has('li:not(.list-header):visible').length != 0);
});
Basically, what the above does is toggling the .list-header (I've wrapped it in the .each() in order to demo different lists) depending on whether the list .has() :visible li elements that are :not(.list-header).
UPDATE
Now it works. Sorry.
You could use the :visible and :not selectors to see if there are any elements present when you change the visibility. This example toggles the visibility when clicking the elements, and hides the header if there are no elements present:
$('li:not(".list-header")').click(function(){
$(this).toggle(10,function(){
var l = $(this).parent().children('li:visible:not(".list-header")').length
if (l>0) $(this).parent().children('li.list-header').show();
else $(this).parent().children('li.list-header').hide();
});
});
working example: http://jsfiddle.net/LDG4J/4/
There is no lh element in HTML. References: HTML5, HTML4.01, HTML 3.2. (You've removed the lh from the question.)
Instead, use an li with a class you style as you see fit (or if you're targeting recent-enough browses, no class required; just style li:nth-child(1) or li:first-child), and just don't hide that li (which will keep the ul visible):
<ul>
<li class='header'>Header</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
Update: I may have misunderstood. If you want to hide the header but keep the ul visible in some way:
A ul with no visible li elements will typically be invisible because it won't have any dimensions. You can override that with CSS, styling the ul to have a specific size (live example):
CSS:
ul.foo {
width: 5em;
height: 5em;
background-color: #eee;
border: 1px solid #aaa;
}
HTML:
<p><code>ul</code> with no visible children:</p>
<ul class='foo'>
<li style="display: none">This is hidden</li>
</ul>
<p><code>ul</code> with a visible child:</p>
<ul class='foo'>
<li>Visible child, note that it wraps</li>
</ul>
And of course you can apply that via jQuery rather than with a static CSS rule:
$("ul.foo").css({
width: "5em",
height: "5em",
backgroundColor: "#eee",
border: "1px solid #aaa"
});
...so you could do that when you're hiding all of the ul's elements, and undo it when showing at least one of them. After making a change:
var ul = $(/*...selector for the relevant list...*/);
if (ul.find('li:visible')[0]) {
// There's at least one visible `li` child
ul.css({/*...styles for when the list is not empty...*/});
}
else {
// There are no visible `li` children
ul.css({/*...styles for when the list is empty...*/});
}
...or better yet, add/remove a class.
try this:
$("ul li:not('.list-header')").each(function(index, val) {
if ($(this).text() == '') {
$(this).hide();
}
});
if (! ($('ul').has("li:visible:not('.list-header')").length)) {
$('li.list-header').hide();
}

Categories

Resources