Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
My javascript is the weakest of my front-end web knowledge and I assume that's a much more efficient way to achieve my functionality than how I've done it.
Basically, I have a site where you have some <li> items and when clicked they show a particular div and if another div (linked to another <li> item) is currently visible it hides it and shows its respective div. It also assigns an active class to the <li> item to provide a different coloured icon for the active section (standard UX practice).
Here's my HTML and Javascript function.
<li id="general">General</li>
<li id="blog">Blog</li>
<li id="twitter">Twitter</li>
And the javascript (it hurts just looking at it)
$(document).ready(function() {
$("#general").addClass("active");
$("#general").click(function() {
$(".data-tab").hide();
$(".settings-general").toggle();
$("li").removeClass("active");
$("#general").addClass("active");
});
$(".settings-twitter").hide();
$("#twitter").click(function() {
$(".data-tab").hide();
$(".settings-twitter").toggle();
$("li").removeClass("active");
$("#twitter").addClass("active");
});
$(".settings-blog").hide();
$("#blog").click(function() {
$(".data-tab").hide();
$(".settings-blog").toggle();
$("li").removeClass("active");
$("#blog").addClass("active");
})
});
Don't get me wrong it works well! But it just looks exhausting and there's probably a much quicker way jQuery can achieve this. Any advice for a JS beginner?
Just create a single function to accomplish the same thing twice, or you could just loop over the code for each you wish to setup.
function setUp(name){
$(".settings-"+name).hide();
$("#"+name).click(function() {
$(".data-tab").hide();
$(".settings-"+name).toggle();
$("li").removeClass("active");
$(this).addClass("active");
});
}
setUp('blog');
setUp('twitter');
Data-drive the whole thing using data- attributes on the options. The same code then works on any number of items without changes to code:
http://jsfiddle.net/TrueBlueAussie/8hvofd6m/2/
$(document).ready(function () {
$(".menu:first").addClass("active");
$('.settings-general').show();
$(".menu").click(function () {
var $active = $(this);
// Unhilight the inactive items
$(".menu").not($active).removeClass("active");
// Then highlight just the active item
$active.addClass("active");
// Seek the target using a jQuery selector in the data-setting attribute
var $setting = $($active.data('setting'));
// Hide the others
$('.settings').not($setting).hide();
// Show the selected one
$setting.show();
});
});
The data-setting attributes can be any selector, class, id or complex. so you can do cool stuff like:
<li class="menu" data-setting="#info .subinfo:first">First info</li>
You can set a single class on a parent container and use css to hide the elements, something like:
<style>
div.tab { display: none }
body.general li.general { font-weight: bold; }
body.general div.tab.general { display: block; }
body.blog li.blog { font-weight: bold; }
body.blog div.tab.blog { display: block; }
body.twitter li.twitter { font-weight: bold; }
body.twitter div.tab.twitter { display: block; }
</style>
<body>
<ul>
<li class="general">General</li>
<li class="blog">Blog</li>
<li class="twitter">Twitter</li>
</ul>
<div class="general tab">general tab</div>
<div class="blog tab">blog tab</div>
<div class="twitter tab">twitter tab</div>
<script>
$('li').click(function () {
$('body').attr('class', $(this).attr('class'));
});
</script>
</body>
See http://jsfiddle.net/szzdyp1n/ for a working example.
Related
I'm not sure that the terms in the question are correct; however I have some HTML (and unfortunately, I am stuck with its structure):
<div>
<ul>
<li>Turn left</li>
<li>Turn right</li>
</ul>
</div>
<div class="possible-outcome">
<span id="turn-left"></span>
<p>You step into a puddle.</p>
</div>
<div class="possible-outcome">
<span id="turn-right"></span>
<p>You fall into a ditch.</p>
</div>
What I would like is all possible-outcome divs to become hidden by having:
div.non-actual-outcome {display: none;}
applied to them, as soon as the user selects one of the hyperlinks, except for the div containing the span with the target id, which should have the actual-outcome class applied to it by JS, so it and it alone is displayed:
div.actual-outcome {display: block;}
When the user hits some other link to a span in a possible-outcome div, then that div will become the only one visible (until the user hits a link that isn't to one of those spans).
Here is some sample code:
div.non-actual-outcome {
display: none;
}
div.actual-outcome {
display: block;
}
<div>
<ul>
<li>Turn left</li>
<li>Turn right</li>
</ul>
</div>
<div class="possible-outcome">
<span id="turn-left"></span>
<p>You step into a puddle.</p>
</div>
<div class="possible-outcome">
<span id="turn-right"></span>
<p>You fall into a ditch.</p>
</div>
What is the simplest way to achieve this (and the correct terms in which to ask the question)?
First, add a common class to all your a elements so that they can be distinguished, for example class="tab":
<a class="tab" href="#turn-left">Turn left</a>
Second, hide all div elements by default by adding the display:none property to the CSS selector .possible-outcome (which all div elements have):
div.possible-outcome {
display: none;
}
and use only actual-outcome to hide/show the div you want. No need to use two classes for that, just one will do. If the div has the class actual-outcome then it will be shown, if not then it won't (because it has the class possible-outcome).
Third, when a .tab element get clicked, select its target span along with that span's parent and do some logic: if the span exists and its parent is not currently shown (not having the class actual-outcome), then hide the actually shown div (if exists) and show the current span's parent instead.
Note: If you want to show a div by default just add the class actual-outcome to it:
<div class="possible-outcome actual-outcome">
Full code:
document.addEventListener("click", function(ev) {
var target = ev.target; // get the element that has been clicked
if(target.classList.contains("tab")) { // if the clicked element is a .tab element
var span = document.querySelector(target.getAttribute("href")), // then select that .tab's span to show
parent = span.parentElement; // select the parent of that span (perhaps check if the span exists first to not get the "can't access property parentElement of null")
if(span && !parent.classList.contains("actual-outcome")) { // if the span exists and its parent is not currently shown (not having the class "actual-outcome")
var visibleOutcome = document.querySelector(".actual-outcome"); // then select the current shown element (which we know will have the class "actuall-outcome")
if(visibleOutcome) { // if there is one
visibleOutcome.classList.remove("actual-outcome"); // hide it by remove the class "actual-outcome" from its classList
}
parent.classList.add("actual-outcome"); // and show the current span's parent by adding that same old class
}
}
});
div.possible-outcome {
display: none;
}
div.actual-outcome {
display: block;
}
<div>
<ul>
<li><a class="tab" href="#turn-left">Turn left</a></li>
<li><a class="tab" href="#turn-right">Turn right</a></li>
</ul>
</div>
<div class="possible-outcome">
<span id="turn-left"></span>
<p>You step into a puddle.</p>
</div>
<div class="possible-outcome">
<span id="turn-right"></span>
<p>You fall into a ditch.</p>
</div>
Just for completion, the Divio Cloud interactive debugging checklist for deployments is our implementation of the solution to this problem.
It's like a choose your own adventure story in our Sphinx documentation, to help users identify why a deployment may have failed.
It was was developed on the basis of Ibrahim Mahrir's answer:
One of our actual JS experts (i.e. not me) used my working proof-of-concept based on Ibrahim's answer for the final version.
The JavaScript and CSS are both embedded in the page itself.
The HTML structure is largely determined by the output from Sphinx, hence the need to accommodate the arrangement of elements.
This is the best solution I could come up with. This does not modify the structure by adding any other classes than the ones provided.
HTML:
<div>
<ul>
<li>Turn left</li>
<li>Turn right</li>
</ul>
</div>
<div class="possible-outcome">
<span id="turn-left"></span>
<p>You step into a puddle.</p>
</div>
<div class="possible-outcome">
<span id="turn-right"></span>
<p>You fall into a ditch.</p>
</div>
CSS:
div.non-actual-outcome {
display: none;
}
div.actual-outcome {
display: block;
}
JS:
var outcomeDivs = document.getElementsByClassName('possible-outcome') // selects all divs and returns them as an array
var links = document.querySelectorAll('li') // selects all <li> and returns them as array
// This is turn left li, we will hide turn-right when clicking it.
links[0].addEventListener('click', function(){
outcomeDivs[1].classList.add('non-actual-outcome'); // hides turn-right
links[1].style.display = 'none'; // hides other link
});
// This is turn right li, we will hide turn-left when clicking it.
links[1].addEventListener('click', function(){
outcomeDivs[0].classList.add('non-actual-outcome'); // hides turn-left
links[0].style.display = 'none'; // hides other link
});
CodePen
In my web application there is a left menu that is of very big size. I have placed a button to make small it. Everything is working when I click on button my menu is being hidden and another small menu is being shown. When I click on any link in small menu, another page is loaded and big menu is shown. If I want to see small menu again I need to click button. I want that if any page is loaded, menu should be shown in last form that was on last page (It can be big also if it was in big form on last page).
My code is here
HTML
<div class="flLeft similarHeight">
<ul class="nav metismenu" id="side-menu">
<li class="nav-header">
<div class="logo">Brand Name</div>
</li>
</ul>
</div>
<div class="flLeftsmall">
<ul class="nav smallnavigation">
<li class="nav-header">
<div class="logo">Brand</div>
</li>
</ul>
</div>
<div class="pull-left">
<span><i class="glyphicon glyphicon-triangle-left menu-big"></i></span>
</div>
CSS
.flLeft {
background:#1b3b5e;
width: 220px;
height: 200px;
}
.flLeftsmall {
display: none;
background:#1b3b5e;
width: 80px;
height: 200px;
color: #fff;
}
a{color: #fff;}
jQuery
$(document).ready(function () {
$('.menu-big').click(function () {
$(this).toggleClass('glyphicon-triangle-right glyphicon-triangle-left');
$('.flLeft').toggle('slide');
$('.flLeftsmall').toggle('slide');
});
});
I am using bootstrap and jQuery plugins properly.
You can see my jsfiddle here.
Please help me.!
Can be achieved using sessionStorage or LocalStorage. It's not elegant, but it works.
Within your click event for collapsing the menu, add a storage item to save the state of the menu
sessionStorage.setItem('menuSize', 'small'); // Or big etc, will need to break this up into two click events.
Then on the pages subsequent, check this storage item to see whether the user has chosen the small or bigger menu.
if (sessionStorage.getItem('menuSize') == 'small') {
$('.flLeft').css("display", "none");
$('.flLeftsmall').css("display", "block");
}
Updated fiddle: https://jsfiddle.net/5vjf0ffs/2/
Try this
It uses localStorage. To store value and then use it to check if we shall display either the small or big box.
$(document).ready(function() {
if (localStorage.getItem("slide") == "small") {
$('.flLeft').toggle('slide');
$('.flLeftsmall').toggle('slide');
}
$('.menu-big').click(function() {
$(this).toggleClass('glyphicon-triangle-right glyphicon-triangle-left');
if (localStorage.getItem("slide") == null) {
localStorage.setItem("slide", "small");
} else {
localStorage.removeItem("slide");
}
$('.flLeft').toggle('slide');
$('.flLeftsmall').toggle('slide');
});
});
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I want to create something similar to the expertise section of this site: http://www.theelixirhaus.com/
Basically I just want specific text to appear above the icons inside an <h2> when you hover over them. Each icon hover brings up different text to the same spot. I attached a JSBin with what I have so far. I'm not sure if a <p> within the li is the right thing to use, and how to grab that and display it in the h2.
https://jsbin.com/cefuboxoje/edit?html,css,js,output
demo: http://jsfiddle.net/swm53ran/388/
if you want to keep your original use of the hover, use .hover() instead of .on('hover', function() {})
also, you want to use $(this).find('skills-title').html() to get the value text inside the <p> tag.
i used .mouseenter() and .mouseleave() functions so that when you werent hovering the element, the <h4> text would be cleared.
$(document).ready(function() {
$(".skills").on('mouseenter',function (){
var title = $(this).find('.skills-title').html();
$(".title-shown").html(title);
}).on('mouseleave', function() {
$(".title-shown").html('');
});
});
ps. you had an extra class="skills" in your original jsbin demo in the first <li>. not that it would change anything in this case, just friendly reminder to check your code.
You can use the 'mouseover' and .children().text() to get to your text:
$(".skills").on("mouseover", function (){
var title = $(this).children().text();
$(".title-shown").html(title);
});
Here is the demo!
Here's simplified working example of this behavior:
var $h4 = $('h4');
$('ul').on('mouseover', 'a', function(){
var title = $(this).data('title');
$h4.stop().fadeIn('fast').text( ': '+ title );
}).on('mouseout', function(){
$h4.stop().fadeOut('fast');
});
h3, h4 { display: inline; }
ul li, ul li a { display:inline-block; }
ul li a {
background: #ddd;
color: #000;
padding: 10px;
text-decoration: none;
transition: opacity .3s;
opacity: 0.7;
}
ul li a:hover { opacity: 1; }
<script src='http://code.jquery.com/jquery.js'></script>
<h3>Expertise</h3>
<h4></h4>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
I'm not looking for accordion functionality, but the ability to toggle multiple states when a single element is clicked. I thought this would be extremely simple, and it is. The code simply isn't working. Can anybody take a look at the code and suggest something I might try?
$(document).ready(function(){
$("#nav_header").click(function(){
if (desktopNavigation === 0) {
$("#navigation").css("overflow","hidden");
$("#navigation").css("height","0px");
desktopNavigation = 1;
}
else if (desktopNavigation === 1) {
$("#navigation").css("overflow","visible");
$("#navigation").css("height","auto");
desktopNavigation = 0;
}
else {
}
});
});
The initial value for the variable is as follows:
var desktopNavigation = 0;
The HTML I am trying to effect is in a page with jQuery loaded, and is as follows:
<div id="nav_header" class="trigger">
<ul>
<li>NAV MENU #1 Title</li>
<li>NAV MENU #2 title</li>
<li>NAV MENU #3 title</li>
<li>NAV MENU #4 title</li>
<li>NAV MENU #5 title</li>
</ul>
</div><!--close nav_header-->
<div id="navigation" class="target" style="height:0;overflow:hidden;">
<div id="nav_column">
NAV MENU #1
</div><!--close nav_column-->
<div id="nav_column">
NAV MENU #2
</div><!--close nav_column-->
<div id="nav_column">
NAV MENU #3
</div><!--close nav_column-->
<div id="nav_column">
NAV MENU #4
</div><!--close nav_column-->
<div id="nav_column">
NAV MENU #5
</div><!--close nav_column-->
</div><!--close navigation-->
It may also be pertinent that I am executing this code on a wordpress page, and that it worked perfectly on my local environment.
Your question is lacking context. What does "the code simply isn't working" mean? Where is "desktopNavigation" define? What exactly does "toggle multiple states" mean?
Going off assumptions, people can't give a direct, concise, answers. With that being said, here is an example which hopefully answers your question:
JSFiddle: http://jsfiddle.net/seibert_cody/mk6juczp/1/
HTML:
<div>
<div id="nav_header"></div>
<ul id="navigation">
<li>I</li>
<li>Am</li>
<li>Iron</li>
<li>Man</li>
</ul>
</div>
JS:
$(document).ready(function(){
var state = 0;
var navClassMap = ["red_state", "blue_state", "green_state", "hidden_state"];
// Each click will increment the class of the UL thus toggling multiple states
$("#nav_header").click(function(){
var $navigation = $("#navigation");
// remove the current class
var curClass = navClassMap[state];
$navigation.removeClass(curClass);
// Increment to the next class (loop back to start on overflow)
state = (state + 1) % navClassMap.length;
// Add the new class
var nextClass = navClassMap[state];
$navigation.addClass(nextClass);
});
});
CSS:
#nav_header{
width: 100%;
height: 50px;
background-color: #ef102f;
cursor: pointer;
}
#nav_header:hover{
background-color: #Ff402f;
}
.red_state{
color: red;
}
.blue_state{
color: blue;
}
.green_state{
color: green;
}
.hidden_state{
display: none;
}
From within the code you provided its not clear what the var desktopNavigation initially is, so it will never be === 0or 1.
$(document).ready(function(){
var desktopNavigation = desktopNavigation || 0;
$("#nav_header").click(function(){
if (desktopNavigation === 0) {
$("#navigation").css("overflow","hidden");
$("#navigation").css("height","0px");
desktopNavigation = 1;
}
else if (desktopNavigation === 1) {
$("#navigation").css("overflow","visible");
$("#navigation").css("height","auto");
desktopNavigation = 0;
}
else {
}
});
});
or write:
...
if (desktopNavigation === 0 || !desktopNavigation) {
...
Above your click function, add:
var desktopNavigation = 0;
desktopNavigation is probably undefined.
But if your goal is to hide a div may I suggest using the built in jQuery function .toggle()
$("#navigation").toggle();
Or if you want to toggle multiple, more extensive styles use .toggleClass() to add or remove a custom class.
$("#navigation").toggleClass('hidden');
By "local environment", do you mean you have a wordpress environment set up on your local machine? If the changes are working on your local and not on your remote, I would try:
Clearing your browser's cache and refresh the remote environment
Inspecting the #navigation element using chrome "inspect element" and make sure it doesn't contain any extra css which may be hiding the #navigation
Print to the console when the #nav_header is clicked; this is to make sure the click callback is working as intended
Check to make sure there isn't another element consuming the click which is wrapping #nav_header
One thing I will also note is that you define id="nav_column" multiple times; you shouldn't be using more than one instance of the same ID.
Good luck
Thanks for the suggestions, they're all viable and work just fine. The problem was with Jquery itself.
This must have been a Wordpress thing, but when I changed the version of Jquery that enqueued, everything worked. It worked on my computer outside of wordpress, but as soon as I put it up live, none of the Jquery functions worked.
I changed it from 1.2.1 to 1.11.0. I thought it would be backward-compatible, but it seems like I have a lot to learn about Jquery.
I have an about section, where I've split it up into multiple sections loaded by JavaScript for easier reading. I'd like the side navigation for this to have a different background color if it is both hovered over and if it is the one selected, and ALSO to have a border right with a unique color for each option. I have it working with no problems, but I'm just wondering if there is a more efficient way to do this than the way I currently am.
In a nutshell, the HTML:
<nav>
<p id="bout" onclick="bout()">About Us</p>
<p id="mish" onclick="mish()">Our Mission</p>
<p id="team" onclick="team()">The Team</p>
<p id="how" onclick="how()">How It Works</p>
<p id="poli" onclick="poli()">Policies</p>
</nav>
<div class="actual">
<div id="about">
<h2>About Us</h2>
<p>We are a conglomerate of hoodlums.</p>
</div>
</div><!-- end actual -->
And the JS:
function bout() {
document.getElementById("about").innerHTML= '<h2>About Us</h2><p>We are a conglomerate of hoodlums.</p>';
document.getElementById("bout").style.borderRight='3px solid red';
document.getElementById("mish").style.borderRight='none';
document.getElementById("team").style.borderRight='none';
document.getElementById("how").style.borderRight='none';
document.getElementById("poli").style.borderRight='none';
document.getElementById("bout").style.backgroundColor='ghostwhite';
document.getElementById("mish").style.backgroundColor='bisque';
document.getElementById("team").style.backgroundColor='bisque';
document.getElementById("how").style.backgroundColor='bisque';
document.getElementById("poli").style.backgroundColor='bisque';
}
function mish() {
document.getElementById("about").innerHTML = '<h2>Mission</h2><p>Our mission is to rid the world of dust bunnies.</p>';
document.getElementById("bout").style.borderRight='none';
document.getElementById("mish").style.borderRight='3px solid orange';
document.getElementById("team").style.borderRight='none';
document.getElementById("how").style.borderRight='none';
document.getElementById("poli").style.borderRight='none';
document.getElementById("bout").style.backgroundColor='bisque';
document.getElementById("mish").style.backgroundColor='ghostwhite';
document.getElementById("team").style.backgroundColor='bisque';
document.getElementById("how").style.backgroundColor='bisque';
document.getElementById("poli").style.backgroundColor='bisque';
}
As you can see, it's quite cumbersome to have to explicitly turn off an on each style when clicked. The main key though is to have each border-right be a different color.
Here is a jsfiddle with the whole thing, but for some reason it's not actually acknowledging the JS: http://jsfiddle.net/4CrhD/
Additional random question: Is it possible to link to this page with a different piece of content loaded than about, for example, can I link to this page with "mish()" loaded instead of whats in the HTML?
The best way would be to use CSS. Add remove a class on a parent element and have the CSS apply the right rules.
body.mish #bout{
border-right : 3px solid red,
}
body.bout #bout{
border-right : 3px solid blue,
}
Yes. You need to divide between html and styling. Use CSS!
Then you can change styles e.g. with jQuery.css():
$('#mish').css({
'border-right': '3px solid orange',
'background-color':'ghostwhite'
});
Of course you can define styles in a class. A class describes the styling definition for all elements using a class.
nav > p {
border-right: none;
background-color: bisque;
}
.active {
border-right: 3px solid red;
background-color: ghostwhite;
}
If a button is clicked you can dynamically add and remove a classes with:
$('nav > p').click(function() {
$('nav > p').removeClass('active');
$(this).addClass('active')
});
Because code duplication is bad (and I don't like to set the full innerHTML), you can create a dynamic page like:
pages = {
'bout': {
'id': 'about',
'headline': 'About Us',
'body': 'We are a conglomerate of hoodlums.'
}
}
Extend the above code to
$('nav > p').click(function() {
$('nav > p').removeClass('active');
$(this).addClass('active')
if (pages[$(this).attr('id')]) {
var page = pages[$(this).attr('id')];
$('.actual').first().empty();
var container = $('<div>', { 'id': page.id });
container.append($('<h2>', { 'html': page.headline }));
container.append($('<p>', { 'html': page.body }));
$('.actual').first().append(container);
}
});
Have look at this jsfiddle for a working example
Addressing your "random" question
Additional random question: Is it possible to link to this page with a different piece of content loaded than about, for example, can I link to this page with "mish()" loaded instead of whats in the HTML?
If you want to have links pointing to this page you can parse the window.location.hash object and link with links like page.html#mish.
To set default a "page" we extend our pages object to provide such a information: http://jsfiddle.net/Eu36g/6/
Define your classes in the CSS : bout, mish, about, poli ... For each one put the CSS you want. After that, in the javascript, you just have to change the class of the element (add class or change class, or whatever) and the new CSS will apply
example
document.getElementById("bout").className = "otherclass"