$(this).find(..) alternative - javascript

I find my self doing this but not sure if this is the best way. Here an example.
<ul id="menubar">
<li><a class="menu_item">File</a>
<ul>
<li><a id="menu_file_new">New</a></li>
<li><a id="menu_file_open">Open</a></li>
</ul>
</li>
<li><a class="menu_item">Run</a>
<ul>
<li><a id="menu_run_preview">Preview</a></li>
<li><a id="menu_run_compile">Compile</a></li>
</ul>
</li>
</ul>
JQuery
$('.menu_item').hover(function(){
$(this).find('ul').show();
});
Just wondering is this the best way, find seems a bit overkill?
EDIT: I can't use css because of this: Fails in Opera/IE when an item is clicked/hover it fails in those two browsers. http://jsfiddle.net/cJsn2/1/ this is because of html standard.

You can do this with CSS only
.menu_item ul { display: none; }
.menu_item:hover ul {display: block; }
as for the JavaScript, it's fine, you can use $.children instead of $.find to traverse less nodes

This would be a simple hover script:
// I'm purposely using `toggleClass`, instead of show/hide, to
// have more flexibility with styling
$('.menu_item').each(function () {
var $li = $(this).closest('li');
$(this).hover(function () {
$li.toggleClass('hover');
});
});
with the following css:
ul ul {
display: none;
}
li.hover > ul {
display: block;
}
demo: http://jsbin.com/ehifod/1/

Try doing this with just css
the catch is that you're going to apply the "hover" on the li and not in the a
#menubar li ul{
display:none;
}
#menubar li:hover > ul{
display:block;
}
jsfiddle >

What you want to use is closest. It travels up the DOM-tree to find the first parent element matching the selector:
$('.menu_item').hover(function(){
$(this).closest('ul').show();
});
$(".menu_item").hover(function() {
$(this).next().show();
});

You can use CSS (this is under the assumption that the ul element is contained within the .menu_item element):
.menu_item:hover > ul {
display: block;
}
Demo: http://jsfiddle.net/maniator/cJsn2/
Using the following HTML:
<ul id="menubar">
<li class="menu_item"><a>File</a>
<ul>
<li><a id="menu_file_new">New</a></li>
<li><a id="menu_file_open">Open</a></li>
</ul>
</li>
<li class="menu_item"><a>Run</a>
<ul>
<li><a id="menu_run_preview">Preview</a></li>
<li><a id="menu_run_compile">Compile</a></li>
</ul>
</li>
</ul>

Related

Make CSS Hover work when the element is hidden using javascript

I have a menu where there are the heading and the submenus. Whenever the user hovers over the heading, submenus show up.
And whenever any of the items in submenus is clicked, the submenu is set to hidden using Javascript. Now, when the user hovers over the menu, the submenus don't show up! Please help me to fix this.
function closesSan() {
document.getElementsByClassName('submenu')[0].style.setProperty('display', 'none', 'important');
}
#main:hover .submenu {
display: block!important;
}
<ul>
<li id="main">
List
<ul class="submenu" style="display: none;">
<li onclick="closesSan()">Bacon</li>
<li onclick="closesSan()">Tuna</li>
<li onclick="closesSan()">Chicken</li>
</ul>
</li>
</ul>
I had to write some additional code to get the desired result. Actually, the base problem in your code was important and property {both works same} in sense both get prioritized by code.
So to get rid of I have added an additional class on click and removing that class on every new hover. Hope it will satisfy the needs.
var main = document.getElementById("main");
main.onmouseover = function() {
document.querySelector('.submenu').classList.remove("displayNoneImp");
}
function closesSan() {
document.querySelector('.submenu').classList.add("displayNoneImp");
}
.submenu {
display: none;
}
#main:hover .submenu {
display: block;
}
.displayNoneImp {
display: none !important;
}
<ul>
<li id="main">
List
<ul class="submenu">
<li onclick="closesSan()">Bacon</li>
<li onclick="closesSan()">Tuna</li>
<li onclick="closesSan()">Chicken</li>
</ul>
</li>
</ul>
Since you don't use a pure CSS implementation, use event listeners and avoid using !important whenever possible:
var main = document.querySelector('#main');
var submenu = document.querySelector('.submenu');
var items = document.querySelectorAll('#main li');
main.addEventListener('mouseover', function () {
submenu.style.display = 'block';
});
main.addEventListener('mouseout', function () {
submenu.style.display = 'none';
});
items.forEach(function(item) {
item.addEventListener('click', function () {
console.log('clicked on:', item)
submenu.style.display = 'none';
});
});
.submenu {
display: none;
}
<ul>
<li id="main">
List
<ul class="submenu">
<li>Bacon</li>
<li>Tuna</li>
<li>Chicken</li>
</ul>
</li>
</ul>
When Using !important is The Right Choice
You can try something simple like this:
function closesSan() {
document.getElementsByClassName('submenu')[0].classList.add("hide");
setTimeout(function() {
document.getElementsByClassName('submenu')[0].classList.remove("hide");
},100)
}
#main .submenu {
display: none;
}
#main:hover .submenu {
display: block;
}
#main .submenu.hide {
display: none;
}
<ul>
<li id="main">
List
<ul class="submenu" >
<li onclick="closesSan()" >Bacon</li>
<li onclick="closesSan()">Tuna</li>
<li onclick="closesSan()">Chicken</li>
</ul>
</li>
</ul>
use visibility instead of display
visibility: hidden;
save those kittens

DropDown on MouseOver

onmouseOver of eacuser i want to show the change password as a dropdown(as can seen in attached image) but with my code changes i am getting change password next to eacuser link.Can anyone please give me some hint how to achieve.I attached the two image file.please check for reference
<div id="appLinks">
<ul id="appLinks_list" class="nav">
<span id="appLink_csrname" class="ui-state-default csrname"><a onmouseover="onMouseOver()">eacuser</span>
<li id="appLink_chngpwd" class="ui-state-default chngpwd">Change Password</li>
<li id="appLink_about" rtlOrder="3"><img src="${link.getContextPath()}${msg.get("icon.information")}" border="0px;" align="top">About</li>
<li id="appLink_logout" rtlOrder="2"><img src="${link.getContextPath()}${msg.get("icon.logout")}" border="0px;" align="top">LogOut</li>
<li id="appLink_help" rtlOrder="1"><a target="eachelp" href="$msg.get("eac.helpPath")"><img src="${link.getContextPath()}${msg.get("icon.help")}" border="0px;" align="top">Help</a></li>
</span>
</ul>
</div>
<script>
$(document).ready(function(){
$(".csrname").mouseleave(function(){
//$('#appLink_chngpwd').hide();
$(".csrname li").css("display","none");
});
$(".csrname").mouseover(function(){
//$('#appLink_chngpwd').show();
$(".csrname li").css("display","block");
});
</script>
Any help would be appreciated
You can try doing this only by CSS, for that you need to edit you Markup.
Check this demo
CSS
#appLinks_list ul {
position: absolute;
left: 0;
top:30px;
width: 60px;
list-style: none;
display: none;
}
#appLinks_list li:hover ul {
display: block;
background: #ccc
}
#appLinks_list li:hover {
background: #ccc
}
I have just added the minimum code for showing dropdown on :hover.
from what i understand, use code like this.replace the div id's with your div ids.
$( "#appLink_csrname" ).mouseover(function() {
$('#changepasswordDivId').show();
});
$( "#changepasswordDivId" ).click(function() {
$('#popup').show();// use facebox or fancy box code that you are using for popup here.
});
I think it's although fault in your html code, watch span and a tags
<ul id="appLinks_list" class="nav">
<span id="appLink_csrname" class="ui-state-default csrname">eacuser
<li id="appLink_chngpwd" class="ui-state-default chngpwd">Change Password</li>
<li id="appLink_about" rtlOrder="3"><img src="${link.getContextPath()}${msg.get("icon.information")}" border="0px;" align="top">About</li>
<li id="appLink_logout" rtlOrder="2"><img src="${link.getContextPath()}${msg.get("icon.logout")}" border="0px;" align="top">LogOut</li>
<li id="appLink_help" rtlOrder="1"><a target="eachelp" href="$msg.get("eac.helpPath")"><img src="${link.getContextPath()}${msg.get("icon.help")}" border="0px;" align="top">Help</a></li>
</span>
</ul>
then
<script>
$(document).ready(function(){
$('.csrname').bind('mouseenter', function () {
$('.csrname', '#appLink_csrname').show()
}
$('.csrname').bind('mouseleave', function () {
$('.csrname', '#appLink_csrname').hide()
}
})
</script>

jQuery navigation-items with nested submenus should open on click

I need to add a second level of submenus here.
Is there a dynamic solution, so only one submenu is opened, when clicking on the link?
And when clicking a link to a submenu (in the first submenu), then open this one?
And so on…
I already changed the jsfiddle a little, to have one level of sublevels more: http://jsfiddle.net/cRsZE/363/
Working example with one level of submenus: JSFiddle Demo
HTML:
<ul id="nav">
<li>Home</li>
<li class="parent">About
<ul class="sub-nav">
<li>Johnny</li>
<li>Julie</li>
<li>Jamie</li>
</ul>
</li>
<li>Contact</li>
</ul>
CSS:
#nav ul.sub-nav {
display: none;
}
#nav ul.visible {
display: block;
}
jQuery:
$(document).ready(function() {
$('.parent').click(function() {
$('.sub-nav').toggleClass('visible');
});
});
Source: Creating Drop Down Menu on click CSS
Try,
CSS:
.hidden {
display: none;
}
JS:
$('ul ul').addClass('hidden');
$(document).ready(function () {
$('.parent').click(function (e) {
e.stopPropagation();
$(this).find('ul').first().toggleClass('hidden');
});
});
DEMO

Menu Item Hover JavaScript

If someone could help me point in the right direction that would be awesome as I have been looking for a solution to this issues for hours.
http://jamessuske.com/will/
I have a menu with 3 menu items on it. if you hover over the last two menu items, a div with items from a different list appear. That part works fine, but if I go to roll over the other menu items from another list, they disappear again.
This is my JavaScript:
<script type="text/javascript">
function showGalleryNav(){
document.getElementById('headerNavGallery').style.display = "";
}
function showInfoNav(){
document.getElementById('headerNavInfo').style.display = "";
}
function hideGalleryNav(){
document.getElementById('headerNavGallery').style.display = "none";
}
function hideInfoNav(){
document.getElementById('headerNavInfo').style.display = "none";
}
</script>
And The HTML
<div class="headerNav">
<ul>
<li>Home</li>
<li>Gallery</li>
<li>Info</li>
</ul>
</div><!--headerNav-->
<div class="headerNavGallery" id="headerNavGallery" style="display:none;">
<ul>
<li>Categoies</li>
<li>Products</li>
</ul>
</div><!--headerNavGallery-->
<div class="headerNavInfo" id="headerNavInfo" style="display:none;">
<ul>
<li>William Ruppel</li>
<li>CV</li>
<li>Artist Bio</li>
<li>Video</li>
<li>Contact</li>
</ul>
</div><!--headerNavInfo-->
I've tried different Attributes, but none of them are working, I have also tried switching to jQuery with
$('#headerNavGallery").css("display", "");
also didn't work,
Any ideas would be greatly apperiated.
Actually what you are trying to accomplish is all css-only doable but not with that markup structure. First you need to nest your lists.
<ul class="menu">
<li>item 1</li>
<li>
item 2 with sub
<ul>
<li>sub menu item 1</li>
<li>sub menu item 2</li>
... so on ..
</ul>
</li>
</ul>
some css
.menu li {
position: relative;
}
.menu li ul {
position: absolute;
top: 30px; /* the height of the root level item */
display: none;
}
.menu li li {
position: static; /* or you could float these for horizontal menu */
}
.menu li:hover ul {
display: block;
}
These are pretty much the basics. But I strongly suggest you go and study superfish menu as it's jquery drop drop menu but it degrades nicely with js off, so you could just study the css of it. http://users.tpg.com.au/j_birch/plugins/superfish/
Check that typeo, nvm...
Setting the display property should always have a value "none" or "block", empty("") is a bad reset... try this:
<script>
$(".galleryNavToggle").on("mouseenter mouseleave", function(event){
var headNavGal = $("#headerNavGallery");
if(event.type === "mouseenter"){
headNavGal.show();
}else if(event.type ==="mouseleave" &&
((event.relatedTarget !== headNavGal[0] && $.inArray(event.relatedTarget, headNavGal.find("*")) <=0) ||
$.inArray(event.relatedTarget, $(".galleryNavInfoToggle")) > 0)){
headNavGal.hide();
}
});
$("#headerNavGallery").on("mouseleave", function(event){
var headNavGal = $(this);
if(event.type ==="mouseleave"){
headNavGal.hide();
}
});
</script>
HTML
<div class="headerNav">
<ul>
<li>Home</li>
<li><a href="" class='galleryNavToggle'>Gallery</a></li>
<li><a href="" class='galleryNavInfoToggle'>Info</a></li>
</ul>
</div><!--headerNav-->
<div class="headerNavGallery" id="headerNavGallery" style="display:none;">
<ul>
<li>Categoies</li>
<li>Products</li>
</ul>
</div><!--headerNavGallery-->
AND CSS
.headerNav{
border:thin solid black;
float:left;
}
.headerNavGallery{
float:left;
border:thin solid black;
margin-left:-1px;
}
1) Gallery
You don't need to specify javascript:. This is redundant.
2) It is working exactly the way you programmied it to work. When you mouse-out, it disappears.
3) You have code for "headerNavInfo" but no matching HTML.

2 column layout for submenus

I am trying to create sort of Jquery Ui megamenu's or even suckerfish style. But can not use them as a plugin in my code.
I have a 2 column layout in my sub menus. How do I tweak the existing code to show it in a 2 column layout? Here's my jsfiddle.
To my understanding, i will have to play a lot with css in this. As I tried doing it by having 2 Unordered list in the main list and gave float right and left consecutively and used clear both.
As you can find that one column already exists.the other column would be dynamically updated through ajax call.
Any help would be appreciated.
Here's a simple demo:
http://jsfiddle.net/brvX3/11/
html:
<ul>
<li>Menu item
<div style="display:none">
<ul>
<li>Menu2 item1</li>
<li>Menu2 item1</li>
</ul>
<ul>
<li>Menu2 item2</li>
<li>Menu2 item2</li>
</ul>
</div>
</li>
<li>Menu item</li>
<li>Menu item</li>
</ul>
CSS:
body {
font-family:arial;
font-size:10px;
}
ul, li {
margin:0;
passing:0
}
ul > li {
float:left;
position:relative;
}
ul li a {
display:block;
padding:3px;
width:80px;
background-color:#e0e0e0
}
ul div {
position:absolute;
width:180px;
background-color:#e0e0e0
}
ul ul {
float:left;
width:90px
}
ul li a:hover > div {
display:block;
}
JS:
$("ul a").hover(
function(){ $(this).next().show() },
function() { $(this).next().hide() }
);
$("ul div").hover(
function(){ $(this).show() },
function() { $(this).hide() }
)

Categories