trouble with accordion I am making - javascript

I am building an accordion for school and I feel like it should work. I know I have everything right up until the if else statement. Any suggestions appreciated
$(document).ready(function () {
//
// Set up a click event handler for clicked <li>
//
$('#accordion li').click(function() {
// find first ul that is a child of this (the clicked <li>)
var $nextUL = $(this).children('ul:first-child');
// Select all siblings of the clicked <li> and then
// select any direct children <ul>'s
// that are visible - this is so we can close any visible
// <ul> before opening the <ul> for the clicked <li>
var $visibleSiblings = $(this).siblings().children('ul:visible');
// If any other <ul>s are visible, slide the visible <ul>
// up and then, after the slide up is complete, slide down
// the clicked <li>'s <ul> into view
if ($visibleSiblings.length > 0) {
$visibleSiblings.slideUp('normal', function() {
$nextUL.fadeIn('normal');
});
} else {
// either no <ul>s were open (open the clicked item)
// or the user clicked on the currently open one so close it
$nextUL.slideToggle('normal');
}
});
});

There is no 'normal' for duration with Jquery fadeIn().
$nextUL.fadeIn('normal');
Reference http://www.w3schools.com/jquery/eff_fadein.asp
speed: Optional. Specifies the speed of the fading effect. Default value is 400 milliseconds
Possible values:
milliseconds
"slow"
"fast"

Related

Make current div change relevant menu tab to active

In my mobile project I can press a menu tab (Tab2) and the tab becomes active (with background color for the active class) and the corresponding div (Div2) below will appear on the screen.
If I press another tab, that tab gets active with corr. div etc...all in all, works perfect!
But now I have the opposite problem, I want to press (in my case, swipe) a div onto my screen and have the corresponding tab above to be active (with color). e.g. swipe in Div1 on screen, Tab1 should be active and have a certain background color. Swipe in Div2, then Tab2 should be active instead etc. but can't get it to work.
Below are my li tags:
<ul class="nav nav-pills mobileNavbar">
<li onclick="swipeFunction(0)" class="col-xs-4 tab1" data-index="0">STREAM</li>
<li onclick="swipeFunction(1)" class="col-xs-4 tab2" data-index="1">CHAT</li>
<li onclick="swipeFunction(2)" class="col-xs-4 tab3" data-index="2">IDE</li>
</ul>
And my jQuery:
$('#carousel-example-generic').on('slid.bs.carousel', function() {
var savedIndex = $(this).find('.active').index();
if (savedIndex === 0){
// I want Tab1 to be active here
} else if (savedIndex == 1){
// I want Tab2 to be active here
} else if (savedIndex == 2){
// I want Tab3 to be active here
}
});
For more details into what I'm trying to build, incl. libs, images (and my previous problem, solved by "Pieter"):
Link to a section on horizontal web page
As I commented above, you are doing same thing in all the conditions. All you need to do is, to activate the navigation item by index you are getting from carousel. Try this:
$('#carousel-example-generic').on('slid.bs.carousel', function () {
var savedIndex = $(this).find('.active').index();
$('.nav-pills>li:eq(' + savedIndex + ')>a').css('background', 'yellow');
});
EDIT:
I would recommend to play with a CSS class instead of inline css. Try this:
$('#carousel-example-generic').on('slid.bs.carousel', function () {
var savedIndex = $(this).find('.active').index();
$('.nav-pills>li:eq(' + savedIndex + ')>a')
.addClass("active") // add active class to the current one
.parent().siblings() // select sibling navigation items
.removeClass("active"); // remove active class from the other navigations
});
You conveniently already have classnames "tab1", "tab2", "tab3" on the tabs, which can be matched easily based on savedIndex:
$('#carousel-example-generic').on('slid.bs.carousel', function() {
$('.nav li').removeClass('active'); // clear the old one
var savedIndex = $(this).find('.active').index();
$('.tab'+ (savedIndex+1)).addClass('active'); // add the new one
});
(I believe index() returns an integer, but if not you may need to parseInt it before adding 1.)

javascript function within a function not working?

EDIT: new problem is that even though current_slide.showCurrentSlide(); function is inside the hidePrevSlide function, the showCurrentSLide code is executing before the animation in hidePrevSlide is finished.
I am trying to create a website where if you click an < li > then the < li > will get a class added to it. It will then slide the current visible screen up and hide it and then show the screen corresponding to the < li > (for example, if the < li > is 'home' then it will slide the current existing screen up and hide it and then it would should the '#homeSlide' screen). Here is my code.
$(document).ready(function(){
hideItems(); //this function basically hides all the screens / slides.. The words 'screen' and 'slides' are interchangeable for the time being.
$('#homeSlide').fadeIn(1000); //the default screen to be shown is the home screen
$('#homeSlide').addClass('current'); //to signify that this is the current visible screen
$('#home').addClass('clicked'); //#home is the <li>, so it adds the .clicked class to the <li>
$('#sidebar ul a li').click(function(){ //loops through all <li>'s in the sidebar if an <li> is clicked
var current_slide = $(this);
$('#sidebar ul .clicked').removeClass('clicked'); // when an <li> is clicked, remove .clicked class from any other <li>'s
current_slide.addClass('clicked'); // add .clicked class to the clicked <li> ($(this))
hidePrevSlide(function(){
alert('enter showing step');
current_slide.showCurrentSlide();
});
});
});
and here is my hidePrevSlide function.
function hidePrevSlide(){
var test = $('.current').attr('id');
test = "#" + test; // surrounds the id with a # and the word 'Slide'. This is the id of the screen which should slideUp
$(test).slideUp( function () {
$(test).hide();
$(test).removeClass('current');
});
alert('finished hiding step. Should enter showing step now');
};
Now, when I run the code, it does say 'finished hiding step. Should enter showing step now' but it does not say 'enter showing step' so it doesnt enter the step which should be executed after the hidePrevSlide function is done. How come?
hidePrevSlide needs to call the callback function.
function hidePrevSlide(callback){
var test = $('.current');
test.slideUp( function () {
test.hide();
test.removeClass('current');
});
alert('finished hiding step. Should enter showing step now');
callback();
};
I also removed the use of $(test). If you have an element, there's no need to keep searching for it by ID.

jQuery - have different events if element is on the same row

I have a page with a row of boxes that are responsive........
so the smaller you resize the window the amount of boxes on each row lessens
heres a fiddle to show you whats going on
http://jsfiddle.net/abtPH/6/
Right now the behavior is......if you click on a box then a div appears under it.....if you click on the next box the div slides up a bit then slides down revealing the new content...
I want it so that if the box is on the same row and the user clicks the next one it does not slide up then down but fades the content in
I only want it to slide up when the box is on a different row...like underneath
heres my jquery so far
$('li').on('click', function(e){
$(this).siblings('.active').toggleClass('active', 400).find('.outer').slideToggle();
$(this).find('.outer').slideToggle();
$(this).toggleClass('active', 400);
});
The trick is detecting what is on the same line. For that I think the position() function is what you need. When a list item is clicked, check to see if there is an active one already, if so, check to see if the current and active items have the same top value. If they do crossfade otherwise toggle.
$('li').on('click', function(e){
var active = $(this).siblings('.active');
var posTop = ($(this).position()).top;
if (active.length > 0) {
var activeTop = (active.position()).top;
if (activeTop == posTop) {
active.toggleClass('active', 400).find('.outer').fadeOut('slow');
$(this).find('.outer').fadeIn('slow');
} else {
$(this).siblings('.active').toggleClass('active', 400).find('.outer').slideToggle();
$(this).find('.outer').slideToggle();
}
} else {
$(this).find('.outer').slideToggle();
}
$(this).toggleClass('active', 400);
});
jsFiddle

jquery - on click of menu item or another element will change body background image

I've read many tutorials and can't seem to get it right. Ok I know that the jquery click function works when you are doing something to the exact same element but how do you make it effect another and toggle back?
I have a menu and when I click on an item I want the background (body) to change to an image.
Example:
HTML
<body>
<ul class="menu">
<li class="menu-item"><a>item 1</a></li>
<li class="menu-item"><a>item 2</a></li>
<li class="menu-item"><a>item 3</a></li>
</ul>
</body>
JQUERY
$(".menu-item a").click(function () {
$(body).css('background', 'http://example.com/image.png'); <-- first menu item
$(body).css('background', 'http://example.com/image.png'); <-- second menu item
$(body).css('background', 'http://example.com/image.png'); <-- third menu item
});
You can use .index() - DEMO
$("a").on("click", function(e) {
e.preventDefault();
var i = $("li").index( $(this).parent() );
if ( i === 1 ) {
$('body').css('background', 'beige');
} else if ( i === 2 ) {
$('body').css('background', 'honeydew');
} else {
$('body').css('background', 'pink');
}
});
Does this seem about like what you're trying to do?
$(".menu-item a:nth-child(1)").click(function () { // first menu item
$(body).css('background', 'http://example.com/image.png');
});
$(".menu-item a:nth-child(2)").click(function () { // second menu item
$(body).css('background', 'http://example.com/image.png');
});
$(".menu-item a:nth-child(3)").click(function () { // third menu item
$(body).css('background', 'http://example.com/image.png');
});
I don't know what you are trying but I could give you hints.
$(".menu-item a") // is an array/jquery collection of all elements that match the selector
.click(function () { // binds the function now to the click event of every item found
$(this); // is now the currently clicked element
// you can now traversal with $(this) for example
$(this).siblings(); // will be a collection of all surrounding elements
$(this).next(); // is the next element after the current one, can be chained like:
$(this).next().next(); // but I wouldn't recomand
$(this).prev(); // same as next but prev
$(this).parent(); // selects the direct parent element, in your case the li element
$(this).children(); // would select the direct children of the current element
// and so on.... there are much more possibilities
// on every of this possibilities you can do your background change
$("some selector"); // is of course still possible
// i think you are trying to do this:
var menuItems = $(".menu-item a");
menuItems.eq(0).css("background", "url to bg 1");
menuItems.eq(1).css("background", "url to bg 2");
menuItems.eq(2).css("background", "url to bg 3");
})
Look at the Traversing section of the jQuery docu. I would also always recommend to look what jQuery is actually doing. Many people hide behind jQuerys api and have no idea whats happening. This results into many misunderstandings.
You may try something like this
HTML:
<body>
<ul class="menu">
<li class="menu-item"><a name="blue" href="#">item 1</a></li>
<li class="menu-item"><a name="red" href="#">item 2</a></li>
<li class="menu-item"><a name="orange" href="#">item 3</a></li>
</ul>
</body>
CSS:
.red {
background:red;
}
.blue {
background:blue;
}
.orange {
background:orange;
}
Jquery:
$('.menu').on('click', 'a', function () {
var bgColor = $(this).attr('name');
$('body').removeClass().addClass(bgColor);
return false;
});
DEMO
The way I suggest going about this is to grab the position of the element that has been clicked. You can do this by using jQuery's index() function as other posters have suggested. Remember this will give you a zero-based index of the position which means that the position counting starts at 0 as opposed to 1.
Based on the item that has been clicked, you assign a CSS class to the target item which is the body element based on the sample code you provided.
Also, I noticed that your JS comments are still invalid even they were edited. Single line comments in JS use a double forward slash, // whereas multiline comments begin with /* and are closed by */.
This is my solution: http://jsfiddle.net/tgZUK/.

Jquery getting two divs to act as one

I have the following code for my popup menu, the parent link is the top level link. It causes a popup to show. Popup fades in and fades out when the mouse enters and exits parent link.
However, I need it to not fade out the popup, if the mouse is over the popup! At the moment, as soon as the mouse enters the popup it fades it out. I need both divs to act as one for the hover, if this makes any sense!
// Hovering over the parent <li>
ParentLink.hover(
function()
{
Popup.fadeIn(300, function() {
});
},
function()
{
Popup.fadeOut(400, function() {
});
}
);
You should nest the popup inside the parent. This way when you move the mouse from the parent to the popup, the parent will still be in a mouse-over state because popup's mouse-over event is bubbled onto the parent. When the mouse is out of the parent (plus its children), mouse-out event will fire on the parent.
Edit
If you are not able to (or want to) change the markup, one possibility is to move the elements to the recommended positions using jQuery, like:
ParentLink.append(Popup); // moves the Popup element from its current position
// and places it as the last child of ParentLink
Most probably you'll have to modify your CSS to match the changes so you may want to think first.
you could unbind the hover-event for the parentlink on completion of the fadein.
Popup.fadeIn(300, function() {
$(ParentLink).unbind('hover');
});
This is not a direct answer to your question but a hint how this could work.
Why don't you nest the the 2nd <div> into the first one, so the out will not occur?
<div id="ParentLink">
<div id="Popup"></div>
</div>
Have #ParentLink { display: relative; } and #Popup { display: absolute; } and you will be fine.
But for those menu's I would always use a nested unordered list structure like this one:
<ul id="topLevel">
<li id="level1item">
Link
<ul id="subLevel">
<li>
Link 2
</li>
</ul>
</li>
</ul>
As said, unbind the event while you are hover the popup and then re-bind it when you are hovering out :
ParentLink.hover(
handlerIn,
handlerOut
);
var handlerIn = function()
{
Popup.fadeIn(300, popupFadeIn);
};
var handlerOut = function()
{
Popup.fadeOut(400);
};
var popupFadeIn = function() {
$(ParentLink).unbind('hover');
$(this).mouseleave( function () {
$(ParentLink).hover(
handlerIn,
handlerOut
);
});
};
btw, I didn't tested this
You can try this:
var inn;
$('ParentLink').hover(function() {
inn = false;
$('p').fadeIn(1000);
},
function() {
$('Popup').bind('mouseenter mousemove',
function() {
inn = true;
}).mouseout(function() {
inn = false;
});
if (!inn) $('Popup').fadeOut(1000);
});

Categories