advanced jquery loop to hide nav - javascript

So I doubt this is advanced jquery, but for me it is since I literally just learned it this week. I wrote everything I need actually on here my only problem is, and I know it's because I am new to jquery, but when you click menu, then any one of the nav options, then back, it's not hiding the content or hiding the nav when content is present, even though I wrote it so it should (it works only one time, and since I am new I know this is why, something wrong with my syntax). Any suggestions?
HTML
<script>
$(document).ready(function () {
//$('ul:first').hide();
//$('ul li').hide();
$('nav>li').hide();
$('ul').hide();
$('h2').hide();
/*('h1>').click(function (event) {
$('nav>ul li:hidden').each(function(i) {
$('nav>li').show();
$('h1').hide();
$(this).delay(i*600).fadeIn(200);
});
$('nav>ul li:visible').each(function(i) {
$('h1').hide();
});*/
$('a.btnDown').click(function () {
$('body').css('background', 'tomato');
$('nav>ul li:hidden').each(function(i) {
//$('nav>h1').fadeOut(300);
//$('nav>ul').fadeIn(200);
$('h1').hide();
$('nav>ul').delay(i*600).fadeIn(200);
return false;
});
}); //closes a.btnDown
$('nav>li').click(function () {
$('nav>ul li:visible').each(function(i) {
$('h1').show();
$('nav>li').hide();
$('ul li').hide();
//clearTimeout(fadeTimeout);
$('nav>li').delay(i*600).fadeOut(200);
}); //closes visible i
return false;
}); //closes a.btnDown
//all the content elements
var $suls = $('body>aside>ul');
var $as = $('a.contentDown').click(function () {
$('h2').show();
var $smL = $('h2');
$smL.animate({
left: 300})
//move nav out of way
var $nav = $('.navBar');
$nav.animate({
right: 300})
//move menu out of way
var $menu = $('.menu');
$menu.animate({
bottom: 300})
//hide visible content item
$suls.filter(':visible').hide();
//display the content item in the same position as the clicked contentDown
$suls.eq($as.index(this)).fadeIn(500);
return false;
}); //closes contentDown
$('a.bck').click(function() {
var $aAside = $('aside');
$aAside.animate({
left: 300})
var $smL = $('h2');
$smL.animate({
left: -300})
//move nav back in way
var $nav = $('.navBar');
$nav.animate({
left: 10})
return false;
}); //closes bck click
}); //closes .ready()
</script>
</head>
<body>
<h1 class="menu"><a class="btnDown" href="#"> Main Menu </a></h1>
<nav class="navBar" >
<li><a class="menuShow" href="#"> Assignment 6 </a></li>
<ul>
<li><a class="contentDown" href="#" > Part One </a></li>
<li><a class="contentDown" href="#"> Part Two </a></li>
<li><a class="contentDown" href="#"> Part Three </a></li>
<li><a class="contentDown" href="#"> Student Notes 1 </a></li>
<li><a class="contentDown" href="#"> Student Notes 2 </a></li>
<li><a class="contentDown" href="#"> Student Notes 3</a></li>
</ul>
</nav>
<h2 id="round"><a class="bck" href="#"> Back </a></h2>
<aside>
<ul>
<li> Interactive media has been apart of my life since as long as I can remember. I have always been fascinated with any form of media including television, video games, handheld games, or websites. However before attending school to study interactive media, I never noticed the little things that can really affect the experience for a user. One item in particular being diegetic elements. Diegetic elements are objects within a media that only the user knows about. For instance, in a video game a diegetic element would be the items you see on the side of the screen that inform you how much health or ammo you have remaining. These are necessary components for they are needed to tell the player perhaps where to go for their next objective, or if any enemies are around you. We have also been exposed to 'non-diegetic' elements that act just the opposite of diegetic ones. Non-diegetic elements are items inside interactivity that are supposed to be there. This is a way of implementing a diegetic element into the space of the world you create. For example, a non-diegetic element would be the ammo bar being placed on the gun, instead of a static bar on the side of the screen. Some patterns being used in interactive media today include the majority of diegetic elements that would at one time be diegetic, but attempting to translate it into a non-diegetic element. </li>
</ul>
<ul>
<li> One ways people have done this is throwing elements in the world that would be believable to the player that they should be there. Instead of throwing a sidebar with your gun ammo and grenade count, it would make sense if a game is placed in modern-time that we would have technology available to put that information on the gun. One of the biggest examples of great uses of non-diegetic elements in the way the players health is damaged. Older games will have a health bar, but more modern games will mostly have a “shock” state where the screen might turn red, or your player begins to lose the ability to act normal when they are under fire. Does this mean we should stop using diegetic elements altogether? This is a question anyone in any form of interactive media should be asking themselves. The problem is that you can have too much non-diegetic presence that would confuse the user instead of help them which was originally intended. Resident Evil received a lot of harsh criticism for their lack of diegetic presence to help the player finish the game. It was hard for the user to be able to tell when the character was going to die based on their health system. If you received damage your character will hunch over, but it's unclear how much damage you're taking. The user will often die </li>
</ul>
<ul>
<li> without knowing whether or not you should have died, as opposed to a health bar that would show you. Contrary to too much non-diegetic presence, is too much diegetic elements. In titles such as World of Warcraft, or League of Legends, some are simply overwhelmed by the fact that half of the screen is objects that you are supposed to be aware of but until you learn the game they make as much sense as flying pigs. In conclusion, it is best to find that medium for any interactive media that has non-diegetic or diegetic elements. It is different for each occasion, for a first-person shooter the need for diegetic elements is acute, while in a complex game like World of Warcraft it is necessary. Websites are the same, and it would be logical and smart for developers to start thinking about how we can eliminate clutter, and turn it into a non-diegetic element for the user. </li>
</ul>
<ul>
<li> Content 4 </li>
</ul>
<ul>
<li> Content 5 </li>
</ul>
<ul>
<li> Content 6 </li>
</ul>
</aside>

Browsed through your page a little bit and got: Uncaught ReferenceError: i is not defined
then, i noticed, that you are not declaring i in $('nav>li').click(function () {, don't really understand your logics, since it is not working, but fix it.

You can easily use hide(). Ive updated the code (starred line) and now it works. Just an insert example to show how you'd select it, not optimized code.
$('a.bck').click(function() {
var $aAside = $('aside');
**$('aside>ul>li:visible').hide();**
$aAside.animate({
left: 300
})
var $smL = $('h2');
$smL.animate({
left: -300})
//move nav back in way
var $nav = $('.navBar');
$nav.animate({
left: 10
})
return false;
}); //closes bck click

Related

Conditional link with Javascript on Wordpress

I am trying to create a conditional link based on the width of the window. It's possible there's a better way to do this that I haven't thought of.
There is a horizontal row of square "buttons" with image icons and titles, and when clicking one of the buttons, a small info window drops below the row of "buttons." I used this Javascript for that:
jQuery(function($)("#individuals-full a").click(function(e){
e.preventDefault();
jQuery(".toggle").hide();
var toShow = jQuery(this).attr('href');
jQuery(toShow).show();
});
The problem is that, because there are so many buttons, which collapse to a vertical row on mobile view, it is impractical. The reason being that the "info" window is below all the buttons here, which creates an issue for the user having to scroll very far, and possibly not being aware that there even is a window below all the buttons.
What I would like to do is create a link for every button, which goes to a separate page (one for each button), if the window width is below a certain amount (let's say 700px), rather than displaying the "info" window below all the buttons.
Here is the HTML for the div with all the buttons, but shortened to just include the code for one of the buttons:
<div id="individuals-full"><h1 style="text-align: center;">We assist individual clients to find personalized solutions involving:</h1>
<ul>
<li><div id="fiance" class="individual-icons"><img class="aligncenter size-medium wp-image-1268" src="finance-visas-01- 300x300.png" alt="" width="300" height="300"><h1 style="text-align: center;">Fiancé Visas</h1></div></li>
</ul>
</div>
<div id="info-panel">
<div id="fiance-content" class="toggle" style="display:none"><hr/>
<h2>Best If You Want to Avoid a Long Separation</h2>
When the most important thing is for a couple to be together as quickly as possible, then the fiancé visa usually delivers.  The average processing time (and thus, a good estimate of the period of separation from each other) is 6-8 months, the period from application to admission to the U.S.
</div>
I take it that it's your e.preventDefault(); that's stopping the proper click function so just reinstate it when you're on mobile.
Get the width of the window, then within your function add an if statement to check if the window width is bigger than mobile, if it is then run this function. If you're on mobile, it'll get skipped.
var viewportWidth = jQuery(window).outerWidth();
jQuery(function($)("#individuals-full a").click(function(e){
if ( viewportWidth > 768 ) {
e.preventDefault();
jQuery(".toggle").hide();
var toShow = jQuery(this).attr('href');
jQuery(toShow).show();
}
});

Rotating through divs (hide/fade in) with jQuery

I'm currently in the process of creating a news carousel. On the left panel i have the three titles of each news item, to the right i have an image associated with that news item, and in the bottom right i have three "navigational blocks" for each item.
In my example, when you click a link on the left, it will display the associated content in the larger right hand panel. This also applies for the navigational blocks in the bottom right. If you click one of those, the associated item will be displayed in the larger panel.
The last thing i need to achieve is an auto rotation of these news items. On load, item one will be displayed with "link 1" highlighted, and "block one" of the navigational blocks highlighted. After say, 10 seconds, "link 2" will become highlighted with the "block 2" highlighted and the associated content in the middle being displayed. So on, so forth.
http://codepen.io/anon/pen/wDiGy - Here's a code pen version of it so far.
Code highlighted below:
<div id="title-container">
<ul>
<li>
Link 1
</li>
<li>
Link 2
</li>
<li>
Link 3
</li>
</ul>
</div>
<div id="image-container">
<div class="image1 image" itemID="1">1</div>
<div class="image2 image" itemID="2">2</div>
<div class="image3 image" itemID="3">3</div>
<div id="circular-nav">
<li></li>
<li></li>
<li></li>
</div>
jQuery for selecting each item
$('.image:first').show();
$('.title, .circle-title').click(function(){
$('.image').hide();
var itemID = $(this).attr('itemID');
$('.image[itemID="' + itemID + '"]').fadeIn('fast');
});
I will be changing the HTML to integrate into the CMS i'm using, but the class names won't be changing.
Any assistance would be greatly appreciated.
UPDATE: I've managed to get 99% of the way there by fiddling around with it. I now have one hurdle. I'm using .next() to reach each item. If there are three items and it reaches the end, how do you return to the beginning? (PEN Updated)
Use a setInterval to trigger the tile change/image change function for every 10 seconds.
setInterval(function(){
//Code for changing the tile/image
},10000); //Milliseconds
You can put your existing function in a variable and use it for click as well as for interval. Also, since you're passing some information with the click, you can store the ids in an array and increment/reset counter after all the images have been cycled through.
Update:
Working Fiddle!
http://jsfiddle.net/hc4py/ (with only links stylized, not bullets)
setInterval(function () {
var $cur = $('a.active');
var i = $cur.closest('li').index(); //parent 'li' of first active link
$('.image:visible').hide(); //hide visible image
$cur.removeClass('active');
//if active 'a's parent li is the last one
if ($cur.closest('li').is(':last-child')) {
$('.image').eq(0).fadeIn('fast'); //show first image
$cur.closest('ul').find('li:first-child').find('a.title').addClass('active');
}
else {
$('.image').eq(i + 1).fadeIn('fast');//show next image
$cur.closest('li').next().find('a.title').addClass("active");
}
}, 2000);
.title.active{color:red;}
I found a simple solution which just involved an if statement to check the length of the item. Once it ended, it was able to loop around correctly.
setInterval(function () {
if ($('.image:visible').next().length === 0) {
$('.image').hide();
$('.image:first').fadeIn();
} else {
$('.image:visible').hide().next().fadeIn('fast');
}
}, 2000); //Milliseconds

Hide what ever exceeds 720px and display the hidden area onClick?

I am trying to make a bunch of <li>'s which are placed next to each-other and they look like boxes; to display 10 every time. The rest to be hidden and to be displayed onClick.
So it should look something like this:
The <li>'s has to be placed in the same <ul> and have no or the same class. So basically the HTML should look something like this:
<ul id="bxs" class="tab1">
<li id="item-1">1</li>
<li id="item-2">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
<li id="item-6">6</li>
<li id="item-7">7</li>
<li id="item-8">8</li>
<li id="item-9">9</li>
<li id="item-10">10</li>
<li id="item-11">11</li>
<li id="item-12">12</li>
<li id="item-13">13</li>
<li id="item-14">14</li>
<li id="item-15">15</li>
<li id="item-16">16</li>
<li id="item-17">17</li>
<li id="item-18">18</li>
<li id="item-19">19</li>
<li id="item-20">20</li>
</ul>
and... this is my question. How can I make them act like this: http://jsfiddle.net/mnCck/6/show/ so if you click on the button, the other 10 appear etc. (On the example, I used 2 ul's and I hide the one and display the other onClick)
Why I need to do this?
Basically, this is a little bookmark page for a client. The boxes will be the bookmarks and they will be created one by one dynamically like this: http://jsfiddle.net/WNZdr/show/ So if you notice, every time you create a box, it gets an ID and it ends up to be like the html I pasted above. I want only 10 of the boxes to be visible and when the client reach that limit then the boxes will be hidden and they will look like they are in another tab so they can be accessed using the nav buttons.
I am not new with javascript or css, it's just I cant think of a way of doing this. I was thinking to place a div ontop of which hides everything out of the range of 720px and then when the nav button is clicked, hide the li's, push them with css at right:720px and display them again. That will look and feel that they are in tabs?
Sorry if the title is somehow confusing, I don't know how to describe all this in a title.
NOTE: Question was not tagged with javascript or jquery, but your example used jquery so I assumed the solution could as well.
You can use overflow: hidden and then adjust the scrollTop.
http://jsfiddle.net/WNZdr/1/
$("#prev").click(function() {
page--;
if (page < 0) page = 0;
$("#bxs").scrollTop(page * 70);
});
$("#next").click(function() {
page++;
$("#bxs").scrollTop(page * 70);
// adjust in case next was clicked and there are no more
page = $("#bxs").scrollTop() / 70;
});
This will need slight tweeking to get the heights/offsets just right, but gives the basic idea.

Please cast an eye over my beginners javaScript

I am working on an interface with four main parts:
When a category link is hovered, the projects not in this category are darkened (this seems to be working ok)
When a category link is clicked, the projects not in this category are hidden (seems also to be ok)
The browser window size is detected and a style sheet is chosen to fit. I.e. for older screen or mobile. Go ahead and resize the browser window.
When the browser window is narrow there is an additional script to scroll down to the "main" div.
<div id="container">
<div id="inner-container">
<div id="tag-selector">
<ul>
<li class="all">ALL PROJECTS</li>
<li class="graphic-design">graphic design</li>
<li class="logo-design">logo design</li>
<li class="photography">photography</li>
<li class="web-development">web development</li>
<li class="web-design">web design</li>
</ul>
</div>
<div id="main" role="main">
<p class="items">There are x items in this category</p>
<p class="selected">No category selected</p>
<p class="clicked">No category clicked</p>
<section class="graphic-design">
<p>graphic-design</p>
</section>
<section class="logo-design graphic-design">
<p>logo-design</p><p> graphic-design</p>
</section>
<section class="logo-design graphic-design"><p>etc</p>
</section>
</div>
<footer> </footer>
then here's the javascript. Sorry if it's a bit long. It should be easy enough to read I hope.
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function(){
var xwidth =$(window).width();//get width of user window
all_projects_showing_text="All projects showing. There are " + n + " projects, in " + t + " categories.";
adjustStyle(xwidth);
$("p.items").text(all_projects_showing_text + " Width=" + xwidth);
$(".all").addClass("selected");
tag="all"
});
</script>
<script>
var n = $("section").length;//number of section boxes on page
var t = $("#tag-selector li").length;//categories
t--;
$("#tag-selector li").click(function() {//clicking section filter li
$("#tag-selector li").removeClass("selected");//removes all filtered class
$(this).addClass("selected");//then adds it to the chosen link (li), showing it as current
tag=$(this).attr("class");//var tag is the class name of the chosen link, i.e. category
var split = tag.split(' '); // this splits the class string and puts each item in an array
tag = split[0];//this chooses the first item of the array, hence not including the hilite class
var numItems = $('.'+tag).length
var numItems=numItems-1;//correct for real number
if (tag!="all"){//if the all link is not picked
$("section").hide();// hide all the boxes
$("#main ."+tag).fadeIn();//show all the boxes with the tag class
if(tag=="graphic-design"){
tag="Graphic design"
}
else if(tag=="logo-design"){
tag="Logo design"
}
else if(tag=="photography"){
tag="Photography"
}
else if(tag=="web-development"){
tag="Web development"
}
else if(tag=="web-design"){
tag="Web design"
}
$("p.items").text(numItems+" " +tag+ " projects");
$("p.selected").text(tag +" selected.");
$("p.clicked").text(tag +" selected.");
}
else{
$("section").fadeIn();//else show all the boxes
$("p.items").text(all_projects_showing_text);// all_projects_showing_text at onReady
}
});
</script>
<script>
$("#tag-selector li").hover(function () {
hovered_link=$(this).attr("class");//get the class of the category being hovered
var split = hovered_link.split(' '); // this returns an array
hovered_link = split[0];//remove any other classes apart from the first i.e. remove hilite
if (tag=="all"){// if All are shown
if(hovered_link!="all"){
$("section").not("."+hovered_link).addClass("section_darkened");//darken section which does not correspond with hovered category link
$("section").not(".section_darkened").addClass("outerglow");//add glow to not darkened sections
}
}
else{
}
if (tag==hovered_link){// if the projects are already filtered by this category, say so on hover
$("p.selected").text(tag +" already selected.");
}
else{
var numItems = $('.'+hovered_link).length
var numItems=numItems-1;//correct for real number
$("p.selected").text("Click to see only "+hovered_link+ " projects. (" +numItems+ " projects)" );
}
$(this).addClass("hilite");//hilite on hover over link
}, function () {
$(this).removeClass("hilite");
$("p.selected").text("...");
$("section").removeClass("section_darkened");//darken categories not in the selected category
$("section").removeClass("outerglow");//give the selected category items a glow
});
</script>
<script>
$(function() {
$(window).resize(function() {
adjustStyle($(this).width());
});
});
function adjustStyle(width) {
width = parseInt(width);
if (width < 600) {
$("#tag-selector li").click(function() {// SCroll function for handhelds
$('html,body').animate({
scrollTop: $("#main").offset().top},
'slow');
});
$("#size-stylesheet").attr("href", "css/nav-style-narrow.css");//style sheet for handhelds
} else if ((width >= 440)&&(width < 1040)){
$("#size-stylesheet").attr("href", "css/nav-style-med.css");
} else {
$("#size-stylesheet").attr("href", "css/nav-style-wide.css");
}
}
</script>
If you've gotten this far and had a look, thanks!
So my questions are;
Am I missing break; in my loops anywhere? Not too sure how to use break.
When my CSS file is chosen, there is a flash of the first style before it changes. Is there a way to avoid this?
When the browser is at the narrowest style sheet, and I click on my link, I have problems scrolling back up again afterwards. help?! :-)
Any glaring mistakes or omissions that would make this easier?
I start to feel like I have a lot of script on my one page. Maybe I should put it in a separate file. Would that help?
Is it ok to post multiple questions like this or should they be individual?
Thanks in advance for anyone who has a look.
Answer regarding break:
break stops the execution of the current loop or switch. You should use it in loops in order to stop a loop before the end of the current iteration, or on a condition that is not checked in the loop statement itself. You should use it at the end of a case in a switch block in order not to execute subsequent cases.
In your specific code there don't seem to be any loops or switches, so no place for any break anywhere.
OK, I'll bite, though I'm not going to try to offer a comprehensive list:
There are various ways to deal with the CSS flash issue. The easiest is to hide everything until you've loaded the correct stylesheet, then show everything once it's loaded.
Yes, in general it's always a good idea to put Javascript in separate files - it just makes managing your code easier, especially if you want to reuse any of it on multiple pages.
You're missing a lot of var statements, e.g. for all_projects_showing_text. This is syntactically correct, but a Bad Idea in Javascript, because it makes those variables global, attaching them to the window object. If you need a global variable, you should still declare it with var.
I'm not seeing any place where break would be appropriate, or even possible. You generally use break within a for or while loop to stop looping; I'm not seeing any loops like that in your code. JQuery code often uses .each() instead, or just loops implicitly through all the items in the selection; I rarely see break in code using jQuery, though there are of course times when it might be appropriate.
It's often a good idea to either cache or chain jQuery selectors. For example,
$("section").removeClass("section_darkened");
$("section").removeClass("outerglow");
could be
var $section = $section;
$section.removeClass("section_darkened");
$section.removeClass("outerglow");
or
$("section")
.removeClass("section_darkened")
.removeClass("outerglow");
or even (in this case, since .removeClass() can remove several classes at once):
$("section")
.removeClass("section_darkened outerglow");
Your long else if section starting if(tag=="graphic-design"){ could be better structured as a map + lookup:
var tagTitles = {
"graphic-design":"Graphic design",
"logo-design":"Logo design",
// etc
};
tag = tagTitles[tag];
break is not a function. It's a statement, so you don't add parenthesis.
The page loads before the css is choosen. If you want to target different screen sizes, you could take a look at css3 media queries. Adding the styles at the beginning of the page should work without flickering. You could still use js to choose styles as backup method.
I think you are adding a new click handler on every resize event! That's a lot of animations running on a click, try to set the handler only once.
Missing var, as already mentioned by nrabinowitz. Indentation could be better / more consistent.
JS in Separate files is better.
cacheable by clients -> page gets faster after first visit
reusable by different pages
easier to manage (version control)
Single (well researched) questions are generally better.

hide show div when multiple nested layers exist

function showlayer(layer){
var myLayer = document.getElementById(layer).style.display;
if(myLayer=="none"){
document.getElementById(layer).style.display="block";
} else {
document.getElementById(layer).style.display="none";
}
}
I need this code to close the current layer and them open another. These layers exist in the content div and are nested 12 deep.
For instance:
This is in the body of the container(navigation) to control the content container which is nested 12 deep. (I came up with an idea on my own but it wound up closing all layers making my web page disappear)
<li>US News</li>
Hence when the navigation button marked US News is clicked via the above it opens
Now, if I have US News open, and I click on say Politics (the third nested layer, I want USNews (the first nest layer) to close and only Politics to open (noticing of course that Politics is the Third Layer and USNews is the first layer).. and so forth..
I've attempted if else statements but I have been out of this for years now and am just frustrated beyond belief... any help would be greatly appreciated
You can loop all the layers and hide them before. And only then show selected one.
function showlayer(layer){
var Layers=document.getElementsByTagName("div");
for(i=0;i<Layers.length;i++){
if(Layers.getAttribute("class")=="layer"){
Layers.style.display="none";
}
}
document.getElementById(layer).style.display="block";
}
<li onclick="javascript:showlayer('USNews')"><a href="#" >US News</a></li>
<li onclick="javascript:showlayer('UkNews')"><a href="#" >Uk News</a></li>
<li onclick="javascript:showlayer('ArNews')"><a href="#" >Ar News</a></li>
<div id="USNews" class="layer"></div>
<div id="UkNews" class="layer"></div>
<div id="ArNews" class="layer"></div>
Instead of writing the raw Javascript, why not use a library instead.
In JQuery you could move to the correct layer, and hide or show it relatively easily.
(Probably one line of script tbh.)

Categories