I'm working in a project here for over 30 hours and I might not be thinking straight.
Here's my situation. I have basically 4 divs that changes they background in diferents ways depending on the mouse action.
Lets call those divs here as div_1, div_2, div_3 and div_4.
When the user pass the mouse over the bottons on the menu the div_1 and div_2 should change they background to the background related to the button.
When the user click on a botton all the 4 divs should change they background and keep it even if the user move the mouse elsewhere.
And the last situation that you need to imagine is the one where the user clicked on one botton and after he pass the mouse over another botton. On this case, the div_1 and div_2 will still change but if the user remove the mouse from the menu div_1 and div_2 should return to the background related to the same background as div_3 and div_4.
I would appreciate if someone could help me to realize whats wrong with my code. Tnx.
Here is my code:
<ul>
<li id="menu-a1" onclick="Menu('a1','click');" onmouseover="('a1','over');" onmouseout="Menu('a1','out');" > Menu_a1 </li>
<li id="menu-a2" onclick="Menu('a2','click');" onmouseover="('a2','over');" onmouseout="Menu('a2','out');" > Menu_a2</ </li>
<li id="menu-a3" onclick="Menu('a3','click');" onmouseover="('a3','over');" onmouseout="Menu('a3','out');" > Menu_a3</ </li>
</ul>
<div id=div_1></div>
<div id=div_2></div>
<div id=div_3></div>
<div id=div_4></div>
heres my java script:
function Menu(where, action) {
switch (action) {
case 'click':
if ($('#menu-'+where).hasClass('active')) {
ClearMenu();
$('#menu-'+where).removeClass('active');
} else {
$('#menu-'+where).addClass('active');
ClearMenu();
ActiveMenu(where);
}
break;
case 'over':
ActiveMenu(where);
OverMenu(where);
break;
case 'out':
ActiveMenu(where);
break;
default: break;
}
}
function ClearMenu(){
// Removing Classes
$('#div_1').removeClass('a1 a2 a3');
$('#div_2').removeClass('a1 a2 a3');
$('#div_3').removeClass('a1 a2 a3');
$('#div_4').removeClass('a1 a2 a3');
function OverMenu(where){
$('#div_1').addClass(where);
$('#div_2').addClass(where);
}
function ActiveMenu(where){
// Adding Classes
$('#div_1').addClass(where);
$('#div_2').addClass(where);
$('#div_3').addClass(where);
$('#div_4').addClass(where);
}
and here is my css:
#div_1.a1 {background:url(background_div1_a1.jpg)}
#div_1.a2 {background:url(background_div1_a2.jpg)}
#div_1.a3 {background:url(background_div1_a3.jpg)}
#div_2.a1 {background:url(background_div2_a1.jpg)}
#div_2.a2 {background:url(background_div2_a2.jpg)}
#div_2.a3 {background:url(background_div2_a3.jpg)}
#div_3.a1 {background:url(background_div3_a1.jpg)}
#div_3.a2 {background:url(background_div3_a2.jpg)}
#div_3.a3 {background:url(background_div3_a3.jpg)}
#div_4.a1 {background:url(background_div4_a1.jpg)}
#div_4.a2 {background:url(background_div4_a2.jpg)}
#div_4.a3 {background:url(background_div4_a3.jpg)}
In your OverMenu function, you've got 'where' in quotes, presumably you want to reference the function parameter and not a string? Get rid of the quotes here.
Also, your CSS is wrong: you can't just give it a filename and expect it to know what to do, you have to set the background-image property:
#div_1.a1 { background-image: url(background_div1_a1.jpg); }
Also, in the onmouseover bits in your HTML, you're not actually calling a function. Presumably you want Menu in here.
UPDATE:
I would use jQuery for this. I've done an example on jsFiddle - http://jsfiddle.net/GrahamClark/gLGUQ/4/ - hopefully this is enough to get you started.
Related
I'm new in jQuery and used it right now for a navigation, that slides in and out in mobile or small views. That works fine and correct, but I'm using a plus-icon to open a submenu, that changes into a minus-icon, when the submenu is opened.
But it doesn't change back into the plus-icon, when the submenu is closed.
The code is the following:
$(document).ready(function() {
$('<span class="menu-expander"><span class="plusicon horizontal"></span><span class="plusicon vertical"></span></span>').insertAfter('.level_2');
$('#menu-toggle').click(function() {
$(this).next('#navigation-main').slideToggle();
});
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
$(this).children('span.plusicon.vertical').toggleClass('plusicon vertical');
});
});
I think the "interesting" part might be the second function, the first is still for a hamburger-icon, that opens the navigation, that works (okay, it doesn't show a sliding animation, what the second one do... no idea, why it don't works...).
So the second part is for the plus. When I click on the plus, the submenu slides in and the plus changes to the minus, but when I click back to the the minus it doesn't change back to the plus.
Has somebody any idea why it doesn't work or can explain me, how I can do it work?
Regards,
Markus
The problem is that your selector is trying to find a span with both plusicon and vertical classes but after the first call to this:
$(this).children('span.plusicon.vertical').toggleClass('plusicon vertical');
wich removes said classes, it is not able to find your target span.
To work around this you could assign an id (iconId on the next example) or another class to your icon so it can be allways found
$('<span class="menu-expander"><span id="iconId" class="plusicon horizontal"></span><span class="plusicon vertical"></span></span>').insertAfter('.level_2');
...
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
$(this).children('#iconId').toggleClass('plusicon vertical');
});
Do this :
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
var $icon = $(this).children('#ID OF ELEMENT'); // Would be easier to add an ID to your element whcih you want to alter - limits the error possibilties :)
if($icon.hasClass("CLASS YOU WANT TO GET RID OF"){
$icon.removeClass("CLASS YOU WANT TO GET RID OF");
$icon.addClass("THE CLASS YOU NEED");
else{
$icon.addClass("THE CLASS YOU WANT TO ADD");
}
});
I am at work now so pardon any typing errors.
You basically need to check whether the class that changes the icon to a MINUS symbol is still active - if so you change it back.
I hope it will help.
Points:
to find element good to use find();
better toggle 1 class to show hide element like "show" in example;
With elements inserted with js code better use .on() (for future);
$(document).ready(function() {
$('<span class="menu-expander"><span class="plusicon horizontal">horizontal</span><span class="plusicon vertical show">vertical</span></span>').insertAfter('.level_2');
$('#menu-toggle').click(function() {
$('#navigation-main').slideToggle();
});
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
$(this).find('.plusicon').toggleClass('show');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
.plusicon {display:none}
.show {display:block!important}
</style>
<ul>
<li id="menu-toggle" class="level_2">Toggle</li>
</ul>
<ul id="navigation-main">
<li>test</li>
</ul>
I have li blocks which onclick will change class ID as follows:
onclick = "document.getElementById('procblock1').id = 'procblock1Clicked';"
"document.getElementById('procblock2Clicked').id = 'procblock2';"
"document.getElementById('procblock3Clicked').id = 'procblock3';"
"document.getElementById('procblock4Clicked').id = 'procblock4';"
The line document.getElementById('procblock2Clicked').id = 'procblock2'; should revert any clicked elements (blocks) back to their original ID names.
The code works for changing the original id to the clicked id but doesn't have any effect in reverting previously clicked to the original as per lines 2,3 & 4.
I have searched hard for similar questions but can find nothing that covers this specific issue.
#Matthias - I acted upon your advice and came up with a very simplified jquery solution :
`$(function() {
$(".showinfo").click(function() { //using class instead of ID
$(".showinfo").removeClass("clicked"); //Remove all existing clicks
$(this).addClass("clicked"); //add the class to the clicked element });
});`
Posted solution in case anyone else has same query. Your help was appreciated.
If this really is part of the code you're using lines 2-4 won't work; onclick will only handle the first line. You should wrap it as a function to be called onclick, like onclick = "doStuff()" and add a function doStuff () {/* your code here */}. But that's just guessing as you only provide some part of the code in question.
In addition would be good to know what you want to achieve - in case you want to mark clicked elements, it would be a cleaner approach to add a class, e.g. "clicked" or "active", that you simply remove later on instead of changing ids.
Conundrum for today:
I'm trying to create a function where the divs underneath the image highlight1A, highlight1B gain a class .highlight when the corresponding divs over the image choice1A, choice1B are clicked. So what should happen is when choice1A is clicked, highlight1A is highlighted. Like so:
But the thing that happens is, when I click one choice, it highlights both divs behind the image.
I'm trying to get the most concise function for this exercise because I'm also going to apply it to exercises where there will be more choice divs and more highlight divs. I'd like to use this so I don't have to do much editing on the .js file. I want to be able to focus on editing the HTML so all I have to do is add / subtract divs from the source file according to how many divs are needed for the following exercises.
Javascript:
function choice1 () {
if ($('div[id^="highlight1"]').hasClass('highlight')) {
$('div[id^="highlight1"]').removeClass('highlight');
} else {
$('div[id^="highlight1"]').addClass('highlight');
}
}
HTML:
<div id="choice1A" class="click1A"></div>
<div id="choice1B" class="click1B"></div>
<img src="../../../../images/chapter_5/CH5L4_21.png" width="276" height="147"/>
<div id="highlight1A" class="click1A"></div>
<div id="highlight1B" class="click1B"></div>
Also, if you generous coders would care to offer a few explanations for the codes you provide, it would be much appreciated, as I'm also looking to expand my knowledge of JavaScript and jQuery.
Thank you so much!
I don't know if there is a reason why you are approaching the problem this way, if there is, please comment and I will edit my answer.
But the simplest way to solve this problem is actually really undemanding. Here is a demo I coded for you.
What you need to do is:
Have a container element around your image;
Bind a click event on the container element, and use toggleClass.
And that's it. The event handler will work even while clicking the image instead of the container due to Event bubbling.
HTML
Your HTML could look like this:
<div class="container"><img src="http://www.example.com/image.png"></div>
<div class="container"><img src="http://www.example.com/image.png"></div>
CSS
div.container {
background-color: #fff;
}
div.active {
background-color: yellow;
}
JS
$('.container').on('click', function(){
$(this).toggleClass('active');
});
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.
I have 5 divs with ids; #one, #two, #three, #four and #five. I have a navigation menu linked to each div like this;
<ul>
<li>ONE</li>
<li>TWO</li>
<li>THREE</li>
<li>FOUR</li>
<li>FIVE</li>
</ul>
where each div represents a single page on my website, the the ul works perfectly but is there a way can have a single button like a "next" button that will go to page 2 when clicked and when clicked again will go to page 3 and so on... preferably using some sort of jquery or even javascript
I will respond based on the assumption that this is a purely theoretical exercise and given only the information you have provided. Please note that there are better ways of doing what you ask, as alluded to in the first comment.
However, assuming that you have, as you say, got an identical navigation menu on each page, and that, as you say, each div is on a separate web page, I suggest that you could continue your existing methodology and place a "Previous" and "Next" button on each page, and hook it up manually to the correct page.
For example, on page with #one, you would have buttons that might look like this:
Previous<!-- does nothing.. because you're on the first page -->
Next<!-- goes to page 2 -->
On subsequent pages, you would hard-code the links to the other pages, and on the final page you would blank out the Next button in a similar way to the way the Previous button was blanked out above.
Having said that. You could put all Divs in the same web page, and show/hide them using JavaScript and CSS. For example:
<div id="one" style="display:block;">Div 1</div>
<div id="two" style="display:none;">Div 2</div>
<div id="three" style="display:none;">Div 3</div>
<script type="text/javascript">
function focusOnAParticularDiv(divId)
{
switch(divId)
{
case 'one':
document.getElementById('two').style.display = 'none';
document.getElementById('three').style.display = 'none';
document.getElementById('one').style.display = 'block';
break;
case 'two':
// etc...
break;
case 'three':
// etc...
break;
}
}
</script>
You could then call that JS function on the onClick event of the next/previous buttons.
<input type="button" text="Next" onclick="focusOnAParticularDiv('two');" />
Or something like that...
You could choose to use JQuery's shortcuts if you wish.
Alternatively, you could use an ASP.NET Wizard control :)
As mentioned in some other comments, you can also create the div the user is after at the server side, which would avoid sending ALL the divs to the client on the first request (this would speed up the user's first request). This would mean you do not need any JavaScript, but would also mean that each time the user clicked a button the page would be destroyed and recreated on the server and sent back to the client (a full round-trip), which would have an impact on the number of hits your server gets.
It really depends what you're after and what your criteria are; hence why I have tried to cover several bases for you.
JQuery has a trigger event. You can trigger click event on your links when a user clicks next or previous button.
Something like
$(document).ready(function() {
var links = [];
var cnt=0;
$("ul li a").each(function(i) {
links[i] = this.href;
});
$("#next").click(function(e) {
cnt++;
if (cnt>=links.length) cnt=0;
location.hash=links[cnt].split("#")[1];
e.preventDefault();
});
});