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();
});
});
Related
I'm struggling to make a replica of the effect seen here: https://tu-dresden.de/if you click on Language, Search, Internal and the navigation in the blue header.
I have managed to create this: https://jsfiddle.net/06tfufo6/2/
I would like to keep the slideToggle effect upon clicking and somehow slideToggle each element inside.
Upon clicking the same/active button it should all close. I can't seem to wrap my head around how this can be done.
Thank you
jQuery('.container-box, .slideout-container').hide();
jQuery('.btn-group a').on('click', function() {
var target = "#" + jQuery(this).data("target");
jQuery('.slideout-container').slideToggle();
jQuery('.container-box').not(target).hide().attr('aria-expanded', 'false');
jQuery(target).show().attr('aria-expanded', 'true');
});
.btn-group {
background-color: #002557;
}
a {
color: #fff;
padding: 10px 20px;
}
.slideout-container {
padding: 25px 0;
background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn-group">
Show language
Show search
Search navigation
</div>
<div class="slideout-container">
<section id="top_search" class="container-box" aria-expanded="false">
Section search
</section>
<section id="language" class="container-box" aria-expanded="false">
Section language
</section>
<section id="navigation" class="main-navigation container-box" role="navigation" aria-expanded="false">
Navigation
</section>
</div>
Store the current content in a variable and compare each time is clicked to slide down and up the content, would be something like this:
jQuery('.container-box, .slideout-container').hide();
var current_page,
target = '';
jQuery('.btn-group a').on('click', function () {
var target = "#" + jQuery(this).data("target");
if(current_page === target){
jQuery('.slideout-container').slideUp();
current_page = '';
}else{
jQuery('.slideout-container').slideDown();
current_page = target;
}
jQuery('.container-box').not(target).hide().attr('aria-expanded', 'false');
jQuery(target).show().attr('aria-expanded', 'true');
});
here is working: https://jsfiddle.net/06tfufo6/8/
For the functionality you described, you need to be able to keep track of the initiating element, and then only call your toggle code when the instigating element is clicked (assuming I understood what you were going for). The code below does just that.
You're going to need to tweak the aria-expanded true/false portion of your code, but this should get you going.
jQuery('.container-box, .slideout-container').hide();
jQuery('.btn-group a').on('click', function() {
var target = "#" + jQuery(this).data("target");
let $target = jQuery(this);
// If no other elements have instigator class, add to target
if (!jQuery(".btn-group a.instigator").length) {
$target.addClass("instigator");
}
if ($target.hasClass("instigator")) {
jQuery('.slideout-container').slideToggle();
jQuery(target).show().attr('aria-expanded', 'true');
} else {
jQuery('.container-box').not(target).hide().attr('aria-expanded', 'false');
jQuery(target).show().attr('aria-expanded', 'true');
}
});
Here's a working fiddle.
How would I be able to simplify this jquery code. I feel like I am repeating myself and just wondering if there is a shorter way to write this which I'm sure there is. I am a bit new to javascript and jquery. I have created a two tabs with their own containers with miscellaneous information in them. Basically I want the container to open when it's related tab is clicked on. I also would like the tab to be highlighted when it's active. Also, how would I be able to write code to make all tab containers disappear when you click off from the tab containers.
<!-- HTML Code -->
<div class="sort-filters">
<span class="sort-by active">SORT BY</span>
<span class="filter">FILTER</span>
</div>
<div class="sort-containers">
<div class="sort-by-container">Sort by click me here</div>
<div class="filter-container">Filter click me here</div>
</div>
/* CSS */
.sort-filters {
display: flex;
width: 500px;
height: 30px;
}
.sort-by,
.filter {
background: #CCC;
color: #756661;
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Arial', sans-serif;
cursor: pointer;
}
.sort-by-container,
.filter-container {
width: 500px;
background: #756661;
color: #FFF;
height: 100px;
display: none;
}
.active {
background: #756661;
color: #FFF;
transition: 0.2s;
}
// Jquery Code
js = $.noConflict();
var sort = js('.sort-by');
var filter = js('.filter');
var sortContainer = js('.sort-by-container');
var filterContainer = js('.filter-container');
js(sort).click(function() {
js(filterContainer).hide();
js(sortContainer).show();
js(sort).addClass('active');
js(filter).removeClass('active');
});
js(filter).click(function() {
js(sortContainer).hide();
js(filterContainer).show();
js(filter).addClass('active');
js(sort).removeClass('active');
});
In order to avoid such repetitive actions I like to stick to naming conventions, so that I can apply the ID's, classes or attributes from one element to select other elements, for instance:
<div id="tabs">
<span class="active" data-type="sort-by">SORT BY</span>
<span data-type="filter">FILTER</span>
</div>
Now, all you need is one click handler on #tabs span, and get the data-type of the span you clicked on. You can use that to filter on the classes of the other container elements.
The second thing is that you can attach handler to more than 1 element at the same time. So in your example, js('#sort-containers div').hide(); will hide all the div's that match the selector at once.
results
I changed some classes to ID's, and some classes to data attributes. Here's a fiddle: https://jsfiddle.net/mq9xk29y/
HTML:
<div id="tabs">
<span data-type="sort-by">SORT BY</span>
<span data-type="filter">FILTER</span>
</div>
<div id="sort-containers">
<div class="sort-by-container">Sort by click me here</div>
<div class="filter-container">Filter click me here</div>
</div>
JS:
js = $.noConflict();
var $tabs = js('#tabs span');
$tabs.click(function() {
var $clicked = js(this); //get the element thats clicked on
var type = $clicked.data('type'); //get the data-type value
$tabs.removeClass('active'); //remove active from all tabs
$clicked.addClass('active'); //add active to the current tab
js('#sort-containers div').hide(); //hide all containers
js('.' + type + '-container').show().addClass('active'); //add active to current container
});
As long as you follow the naming convention of data-type: bla in the tabs, and bla-container on the classes in sort-container, you never have to worry about coding for additional tabs.
There might still be things that could be further optimised, but at least it'll take care of the repetition.
Is it possible to add a class to a link inside a li element when a certain part of the page is active?
I have a one page website and would like to change the color of the link when that specific part of the page is reached via scroll.
Here's my HTML:
<header id="header">
<section class="container">
<nav>
<a class="logo" href="index.html">Logo</a>
<div id="menu">
<ul id="links">
<li>Services</li>
<li>About</li>
<li>Clients</li>
<li class="last">Contact</li>
</ul>
</div>
</nav>
</section>
</header>
And here's the CSS:
#menu li a {
color:#7a7a7a;
text-decoration: none;
font-size: 12px;
margin-right:20px;
}
#menu li.last a {
color:#7a7a7a;
text-decoration: none;
font-size: 12px;
margin-right:0px;
}
#menu li.current a {
color: #0086be;
}
What I would like to do is to add the class .current to the link inside the li element whenever that specific part of the page is reached.
I believe this is only possible with Javascript, can anyone point me the right path to achieve this?
Thanks in advance
I think you want something like scrollspy in bootstrap,
you can use it or you can find https://gist.github.com/pascaldevink/2380129 bypascaldevink
or here is the fiddle http://jsfiddle.net/ia_archiver/Kb7xq/
You will require jquery for this,
$.fn.scrollspy = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('scrollspy')
, options = typeof option == 'object' && option
if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.scrollspy.Constructor = ScrollSpy
$.fn.scrollspy.defaults = {
offset: 10
}
$(function () {
$('[data-spy="scroll"]').each(function () {
var $spy = $(this)
$spy.scrollspy($spy.data())
})
})
}(window.jQuery);
Using hover function you can achieve this.i.e. on hover of specific part of the page you add the class to the link present inside the li. e.g.
$('#specificPartOfPageId').hover(function(){
$('#links').children().children('a').addClass('current');
});
This would add .current class to every link present inside that UL element.
Hope this helps.
If I have understood correctly, I guess this is what you require: jsFiddle. The CSS and the HTML code remains the same and this is the jQuery code which I've used:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll > 500) {
$("#links li:first-child").addClass("current");
}
if (scroll > 750) {
$("#links li:first-child").removeClass("current");
$("#links li:nth-child(2)").addClass("current");
}
var scrollBottom = $(window).scrollTop() + $(window).height();
if (scroll < 500) {
$("#links li:first-child").removeClass("current");
}
if (scroll < 750) {
$("#links li:nth-child(2)").removeClass("current");
}
});
Basically what happens is that when you scroll down to 500px, the li:first-child is automatically assigned the current class. You can modify the jQuery to suit your needs by adding more if queries as per your needs. You can target different <li>'s in your list using different child-selectors like li:first-child, li:nth-child(2) etc.
I'm trying to make a stupid horizontal nav bar with a drop-down on some of the items. The way I decided to do it is just by putting the drop-down in a div tag. This is easily changeable, i just don't like to go heavy on the html side.
Basically I just want my drop down to work when you hover over the parent element. Additional css is going to be used to make it pretty and positioned better.
Here's my js:
var dropdown = $('.dropdown');
var parent = dropdown.parent();
$(parent).hover(
function () {
dropdown.css('display', 'block');
}
);
Here's my css:
div.nav {
text-align: center;
}
div.nav > ul > li {
margin-top: 15px;
text-align: center;
font-size: 1.25em;
}
div.nav > ul > li {
display: inline-block;
list-style-type: none;
}
div.nav a {
padding: 1em;
}
div.dropdown {
display: none;
background-color: black;
position: absolute;
}
Here's my html:
<div class="nav">
<ul>
<li>Home</li>
<li>
Sample Game
<div class="dropdown">
About it
<br>
Game
</div>
</li>
<li>TP Solutions</li>
<li>Projects</li>
<li>Contact Me</li>
</ul>
<div class="clear"></div>
You should not be using "parent" as a variable name, as it's a reserved word.
$(document).ready(function() {
var $dropdown = $('.dropdown'),
$parent = $dropdown.parent();
$parent.on("mouseover",
function () {
$dropdown.css('display', 'block');
}
);
$parent.on("mouseout",
function () {
$dropdown.css('display', 'none');
}
);
});
According to the oreder this has to be done:
add a jQuery plugin first
Then add your script
so the order will be like this:
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js'>
</script>
<script>
$(function(){
var dropdown = $('.dropdown');
var parent = dropdown.parent();
$(parent).hover(function () {
dropdown.css('display', 'block');
});
});
</script>
Please try the below code.
$(".nav").on("mouseenter","li",function(){
$(this).find(".dropdown").show();
});
$(".nav").on("mouseleave","li",function(){
$(this).find(".dropdown").hide();
});
In your code " dropdown.parent(); " -> this will refer all the parents which have child dropdown and will show the menu. we need to refer current hover parent. Please check the working example in below link.
http://jsfiddle.net/renjith/wX48f/
There are so many good solutions to use jQuery and CSS to show a drop down menus. So you don't need to reinvent the wheel. Here are some examples that you might be able to find one to fit your need.
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>