I'm new to jQuery, I was hoping you guys could help me. I'm trying to make a hover dropdown menu, but it's extremely buggy. Can you help me clean up my Javascript? Look at my code please.
http://jsdo.it/mretchin/4Ewk
It doesn't work on jsdo.it for whatever reason, but it works in Komodo Edit.
Try out the code yourself if you really want to, the problem is mainly the Javascript. Can you help me make it so that when the user hovers over img.menu_class, ul.file_menu drops down, and then, if I wanted, I could hover over #something in ul and it would drop out horizantally, not vertically.
Thanks for helping! I appreciate it!
Should I just give up and make it work in CSS?
You can do something like this:
$(document).ready(function() {
$(".hoverli").hover(
function() {
$('ul.file_menu').stop(true, true).slideDown('medium');
},
function() {
$('ul.file_menu').stop(true, true).slideUp('medium');
}
});
});
And here an example with sub-menus:
$(document).ready(function() {
$(".hoverli").hover(
function() {
$('ul.file_menu').slideDown('medium');
},
function() {
$('ul.file_menu').slideUp('medium');
}
);
$(".file_menu li").hover(
function() {
$(this).children("ul").slideDown('medium');
},
function() {
$(this).children("ul").slideUp('medium');
}
);
});
For anyone who finds this in the future Aram's answer can be shortened with .slideToggle() to handle both up and down.
Here's the modified fiddle
http://jsfiddle.net/4jxph/2009/
If you have a sub-menu set to display: none; it will trigger it also, so what you'll want to do is set it to block, then add something like this
var subMenu = $('li.hoverli > ul > li');
subMenu.hover(function () {
$(this).find("ul").slideToggle(200);
});
And place it right below your first slideToggle. Why don't I just show you?
$(document).ready(function () {
$(".hoverli").hover(function () {
$(this).find('ul').slideToggle('medium');
});
var subMenu = $('li.hoverli > ul > li');
subMenu.hover(function () {
$(this).find("ul").slideToggle(200);
});
});
Not sure if you care but you want to make sure that you run the .stop() method that way the animations dont build themselves up and run over and over. Here's an example
http://jsfiddle.net/4jxph/1335/
$(document).ready(function () {
$(".hoverli").hover(
function () {
$('ul.file_menu').stop(true, true).slideDown('medium');
},
function () {
$('ul.file_menu').stop(true,true).slideUp('medium');
}
);
});
Use the finish function in jQuery to prevent the bug where you rapidly hover your mouse over the menu and out of the menu. Finish is better than the stop function previously suggested.
$(document).ready(
function () {
$(".hoverli").hover(
function () {
$('ul.file_menu').finish().slideDown('medium');
},
function () {
$('ul.file_menu').finish().slideUp('medium');
}
);
});
Aram Mkrtchyan's answer was almost there for me. Problem with his was if you add anything below the menu then it gets all screwy. Here is an example of what I mean, I added a div below his menu:
http://jsfiddle.net/4jxph/3418/
I am submitting this updated answer using div instead of lists and list items (which I find much easier to work with, and way more flexible) and jQuery version 1.9.1
here is link to jFiddle:
http://jsfiddle.net/4jxph/3423/
Here is the code:
--------------- HTML:
<div id="divMenuWrapper1" class="divMenuWrapper1">
<div id="hoverli">
<div class="lbtn">
Actions
</div>
<div id="actions_menu" class="file_menu">
<div>File</div>
<div>Edit</div>
<div>View</div>
<hr />
<div>Insert</div>
<div>Modify</div>
<div>Control</div>
<div>Debug</div>
<div>Window</div>
<div>Help</div>
</div>
</div>
</div>
<div>
testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu testing content below menu
</div>
--------------- Css:
.lbtn
{
display:inline-block;
cursor:pointer;
height:20px;
background-color:silver;
background-repeat:repeat-x;
border:1px solid black; /* dark navy blue */
text-decoration:none;
font-size:11pt;
text-align:center;
line-height:20px;
padding:0px 10px 0px 10px;
}
.divMenuWrapper1
{
height: 25px;
width: 75px;
}
.file_menu
{
display:none;
width:250px;
border: 1px solid #1c1c1c;
background-color: white;
position:relative;
z-index:100000;
}
.file_menu div
{
background-color: white;
font-size:10pt;
}
.file_menu div a
{
color:gray;
text-decoration:none;
padding:3px;
padding-left:15px;
display:block;
}
.file_menu div a:hover
{
padding:3px;
padding-left:15px;
text-decoration:underline;
color: black;
}
--------------- jQuery (to be placed in document.ready or pageLoad()):
$("#hoverli").hover(
function () {
$('#actions_menu').finish().slideDown('fast');
},
function () {
$('#actions_menu').finish().slideUp('fast');
}
);
I know this is probably a bit late but just found this thread saw that your question above about things below the menu 'getting a bit screwy' was unanswered.
If you give your div with the class 'file menu' a position of absolute then it should cease to affect any elements ahead of it as you will have taken it out of the normal flow.
To get a select box to open on hover to the exact height required by its contents, figure out how many elements there are:
JavaScript
function DropList(idval) {
//
// fully opens a dropdown window for a select box on hover
//
var numOptgroups = document.getElementById(idval).getElementsByTagName('optgroup').length;
var numOptions = document.getElementById(idval).getElementsByTagName('option').length;
document.getElementById(idval).size = numOptgroups + numOptions;
}
HTML
<select class="selectpicker" id="heightMenu" onmouseover="DropList('heightMenu')" onmouseout="this.size=1;" size="1">
<option value="0">Any height</option>
etc.
</select>
Related
Here is the answer to the question, thanks to #CumminUp07
I've found this link to be helpful, except that I do not want the suggestions div to disappear after an element is selected in the suggestions div in order to select more suggestions later. I have tried to implement this strategy with the slideUp() and slideDown() jquery functions, but of course that is not as fast as the show() and hide() jquery functions, and trying to speed up the sliding functions ends up stopping the suggestions div from appearing again.
Here is a plunker of what I am currently stuck on:
$('#search').focus(function() {
$('#suggestions').slideDown();
});
$('#search').blur(function() {
$('#suggestions').slideUp();
});
$('#suggestions div').click(function() {
$('#search').val($(this).html());
$('#suggestions').slideDown();
$('#search').focus();
});
#search,
#suggestions {
width: 200px;
}
#suggestions {
display: none;
border: 1px solid gray;
border-top: none;
}
#suggestions div:hover {
background-color: #99CCFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search" value="" />
<br />
<div id="suggestions">
<div>Toronto</div>
<div>Seattle</div>
<div>Dallas</div>
</div>
I do not believe this is a duplicate to Action on blur except when specific element clicked with jQuery, because the timeout does not work well enough for the functionality I desire, nor does it allow you to ensure I can click two different divs while keeping one of those two divs open until a different object in the document is selected.
You can stop the animation from completing and then just show the suggestions
$('#search').focus(function() {
$('#suggestions').slideDown();
});
$('#search').blur(function() {
$('#suggestions').slideUp();
});
$('#suggestions div').click( function() {
$('#suggestions').stop(true,true).show();
$('#search').focus();
$('#search').val($(this).html());
});
Maybe it will help you
$('#search').focus(function() {
$('#suggestions').slideDown();
});
$('#search').blur(function() {
$('#suggestions').slideUp();
});
$('#suggestions div').click(function() {
$('#search').val($(this).html());
$('#search').blur();
});
https://jsfiddle.net/vc15r7qb/
I'm trying to learn how to shorten my jQuery code. Any suggestions or tips would be awesome:
jQuery(document).ready(function($){
$('#checkout_timeline #timeline-4').click(function() {
if ($('#checkout_timeline #timeline-4').hasClass('active')) {
$('#checkout-payment-container').addClass('cpc-visible');
}
});
$('#checkout_timeline #timeline-1, #checkout_timeline #timeline-2, #checkout_timeline #timeline-3').click(function() {
$('#checkout-payment-container').removeClass('cpc-visible');
});
});
To avoid clutter, please find the working version here:
My JSFiddle Code
I know I can use .show() and .hide() but due to other CSS considerations I want to apply .cpc-visible.
There are a handful of things you can improve here. First, you're over-specifying. Ids are unique. No need to select #checkout_timeline #timeline-4 when just #timeline-4 will do. But why even have ids for each li? You can reference them by number using the :nth-child(n) selector. Or better yet, you've already given them application-specific class names like billing, shipment, and payment. Use those! Let's simplify the original content to:
<ul id="checkout_timeline">
<li class='billing'>Billing</li>
<li class='shipping'>Shipping</li>
<li class='confirm'>Confirm</li>
<li class='payment active'>Payment</li>
</ul>
<div id='checkout-payment-container' class='cpc-visible'>
This is the container to show and hide.
</div>
Notice I left the active class, and indeed further initialized the checkout
div with cpc-visible to mirror the payment-is-active condition. Usually I would keep HTML as simple as possible and put "starting positions" initialization in code. But "in for a penny, in for a pound." If we start with payment active, might as well see that decision through, and start the dependent div in a consistent state.
Now, revised JavaScript:
jQuery(document).ready(function($) {
$('#checkout_timeline li').click(function() {
// make clicked pane active, and the others not
$('#checkout_timeline li').removeClass('active');
$(this).addClass('active');
// show payment container only if payment pane active
var paymentActive = $(this).hasClass('payment');
$('#checkout-payment-container').toggleClass('cpc-visible', paymentActive);
});
});
This code is much less item-specific. It doesn't try to add separate click handlers for different tabs/panes. They all get the same handler, which makes a uniform set of decisions. First, that whichever pane is clicked, make it active and the others not active. It does this by removing all active classes, then putting active on just the currently selected pane. Second, it asks "is the current pane the payment pane?" And it uses the toggleClass API to set the cpc-visible class accordingly. Often such "set class based on a boolean condition" logic is simpler and more reliable than trying to pair appropriate addClass and removeClass calls.
And we're done. Here's a JSFiddle that shows this in action.
Try this : You can user jquery selector with timeline and active class to bind click event handler where you can add required class. Same selector but not having active class to remove class.
This will be useful when you add / remove elements and will be more flexible.
jQuery(document).ready(function($){
$('#checkout_timeline .timeline.active').click(function() {
$('#checkout-payment-container').addClass('cpc-visible');
});
$('#checkout_timeline .timeline:not(.active)').click(function() {
$('#checkout-payment-container').removeClass('cpc-visible');
});
});
JSFIddle
Here is one of the ways, you can shorten this code by using :not(). Also its better to use elements than to reference and get them via JQuery always.
jQuery(document).ready(function($) {
var showHideContainer = $('#checkout-payment-container');
$('#checkout_timeline .timeline.active').click(function() {
showHideContainer.addClass('cpc-visible');
});
$('#checkout_timeline .timeline:not(.payment)').click(function() {
showHideContainer.removeClass('cpc-visible');
});
});
try this code its working fine with fiddle
$('.timeline').click(function() {
if ($(this).hasClass('active') && $(this).attr("id") == "timeline-4")
$('#checkout-payment-container').addClass('cpc-visible');
else
$('#checkout-payment-container').removeClass('cpc-visible');
});
This would of been my approach cause you still have to add/remove the active class between each li.
jQuery(document).ready(function($) {
$('ul li').click(function() {
$('ul li.active').removeClass('active');
$(this).closest('li').addClass('active');
k();
});
var k = (function() {
return $('#timeline-4').hasClass('active') ? $('#checkout-payment-container').addClass('cpc-visible') : $('#checkout-payment-container').removeClass('cpc-visible');
});
});
#checkout-payment-container {
float: left;
display: none;
background: red;
color: white;
height: 300px;
width: 305px;
padding: 5px;
}
ul {
list-style: none;
width: 100%;
padding: 0 0 20px 0px;
}
li {
float: left;
padding: 5px 11px;
margin-right: 5px;
background: gray;
color: white;
cursor: pointer;
}
li.active {
background: black;
}
.cpc-visible {
display: block !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="checkout_timeline">
<li id='timeline-1' class='timeline billing'>Billing</li>
<li id='timeline-2' class='timeline shipping'>Shipping</li>
<li id='timeline-3' class='timeline confirm'>Confirm</li>
<li id='timeline-4' class='timeline payment'>Payment</li>
</ul>
<div id='checkout-payment-container'>
This is the container to show and hide.
</div>
Your code look great, i would have written it the same.
bit sure how much it helps but if you like, you can use inline if like this:
$(document).ready(function(){
$('#B').click(function() { (!$('#B').hasClass('active')) ?
$('#A').addClass('active') : ''; });
$('#C').click(function() { $('#A').removeClass('active'); });
});
Link for a live example:
jsFiddle
Have successfully setup a menu which cycles between multiple tabs using Javascript. The issue is I'm using SiteLevel as a search for this site. I want the search box to be a part of the hide/unhide menu but the script (I've also tried the html code for the search box, but still no fix)
I've paired it down to the simplest form of this concept to ensure that it's not some other css or script that's conflicting, but it still opens to a blank box here's the code.
I've pumped it into http://jsfiddle.net/Split98/A3DVa/
Software
Hardware
Supplies
Contact
Search
<div id="nav">
<div id="software">Hello!</div>
<div id="hardware">Yes!</div>
<div id="supplies">Yeee Haw!</div>
<div id="contact">Bingo!</div>
<div id="search"><script type="text/javascript" src="http://www.sitelevel.com/javabox?crid=ze32uipb"></script></div>
</div>
CSS:
#nav div {
display: none;
background-color: red;
height: 200px;
}
jQuery:
$(function(){
var divs = $('#nav div'),
links = $('a');
links.click(function () {
$(this.hash).toggle().siblings().hide();
return false;
});
})
Thanks in advance guys!
LIVE DEMO
Simply use #nav > div in your CSS
Will target only the immediate childrens.Otherwise all DIV elements will be hidden (your search tool)
#nav > div {
display: none;
background-color: red;
height: 200px;
}
edited jQuery
$(function () {
var divs = $('#nav div'),
links = $('a');
divs.eq(0).show(); // if you need it.....
links.click(function ( e ) { // e = event
e.preventDefault(); // instead of return false;
$(this.hash).toggle().siblings().hide();
});
});
I'm trying to change a spoiler but i have problem with javascript code
This is the spoiler:
http://nathan3000.altervista.org/Jdownloader%20Spoiler/zzzz.html
When i click the image "MAC" the spoiler opens. When i click again MAC the spoiler closes. But when i click between the text the spoiler closes again. I do not want the spoiler closes when I click in the middle of the text but only when i click image "MAC". How can i do change selector so it only show/hides when i click the image?I'm still clicking inside the .OS container
I don't understand why the table border doesn't appear on online version while on local version I can see the borders of tables.
The javascript code for spoiler is this:
<script type="text/javascript">
$(document).ready(function(){
$(".nonjs").removeAttr( "href"); //href is needed for users without JS
$('.OS').click(function(){
if($(this).find(".details").is(":visible"))
{
$(this).find(".details").not(":hidden").hide("slow");
return true;
}
else
{
$(this).find(".details").show("slow");
return false;
}
});
});
</script>
<style type="text/css">
<!--
.details {
display: none;
clear: both;
padding: 2px;
}
.nonjs{
cursor:pointer;
}
img {
border: 0px;
}
-->
</style>
Thanks in advance
This is working:
$(document).ready(function(){
$(".nonjs").removeAttr( "href");
//href is needed for users without JS
$('.OS').click(function(e){
if(!$(e.target).parents('.details').length){
if($(this).find('.details').is(":visible"))
{
$(this).find('.details').not(":hidden").hide("slow");
return true;
}
else
{
$(this).find('.details').show("slow");
return false;
}
}
});
});
put your spoiler/ popdown menu directly after your .OS image. right now your popdown is a child of the .OS container, so clicks on it are passed to the .OS click handler.
here is something like you want:
http://tempesthostingservices.com/t/zzzz.html
I want to make a similar navigation menu like what m.facebook.com did.
but this, i want to make it nicely animated slide out from left side of the website.
Flow ::
Click a button > (Menu is hidden by default) Menu Slide out, push the main container to right a bit to fit the menu > Click again > Menu Slide in and hidden again.
I got no idea to make it with javascript or jquery or ajax while i'm new to web development and there are too much of effect scripting language. May i know to achieve this, which is perfect in smoothness ?
Something along these lines... http://jsfiddle.net/HfdXY/
HTML:
<div id="menu">Menu</div>
<button id="openMenu">Toggle menu</button>
CSS:
#menu {
height: 300px;
width: 0px;
border: 1px solid black;
display: none;
}
JS:
$("#openMenu").click(function() {
var menu = $("#menu");
if ($(menu).is(":visible")) {
$(menu).animate({width: 0}, 1000, function() {$(menu).hide();});
} else {
$(menu).show().animate({width: 100}, 1000);
}
});