Open divs and close others - javascript

So I have a section where I'd like to click on the image and have .speaker-info animate open by toggling class .open on .speaker-container to animate the height to reveal .speaker-info while toggling the class .hover for a hover state image. A .fade class also gets toggled on to .speaker-info to change the opacity. I got everything working fine if I click one image and close it with the same location, but when I open one and click another image everything closes, so I'll need two clicks to open the other, and the hover image states on for the previous image.
So I'd like to open one div and then if another image clicked, all close and the recent one opens.. I've been going around in circles trying to figure the best way to do this.. but I keep hitting a wall.
I'm basically triggering everything by toggling css classes to create the opening/closing and hovering.
Here's my code.
Also, I'm looking for opinions on how to make my code more nimble, and more efficient, sometimes I feel like I write waaay to much where I could do the same with a few lines less.
Thanks!
<section id="speakers">
<div class="container">
<div class="row">
<div class='speaker-container'>
<div class="span3 offset1" id="{row_index}">
<div class="speaker-img">
<img src="{speaker_image}" alt="{speaker_name}" class="hover">
<img src="{speaker_hover}" alt="{speaker_name}">
</div>
<h4>{speaker_name}</h4>
</div>
<div class="speaker-info">
<button class="close-speaker">Close</button>
<h3>{speaker_name}{if speaker_title}, {speaker_title}{/if}</h3>
<p>{speaker_bio}</p>
</div>
</div>
</div>
</div>
</section> {!-- /End Speakers --}
Javascript codes
$('.speaker-container').each(function(){
var containerHeight = $(this).height();
$('.speaker-info').css({ 'top' : containerHeight});
});
$('#speakers .span3').on('click', function(){
var containerHeight = $(this).parent('.speaker-container').height();
var h = $(this).next('.speaker-info').height();
var totalHeight = containerHeight + h;
$(this).find('.speaker-img').children().toggleClass('hover');
$('#speakers .span3').not($(this).next('.speaker-info')).next('.speaker-info').removeClass('fade');
if (!$('.speaker-info').hasClass('fade') && !$('.speaker-container').hasClass('open')) {
$(this).closest('.speaker-container').css({'height' : totalHeight}).addClass('open');
$(this).next('.speaker-info').addClass('fade');
} else {
$('.speaker-container').css({'height' : h}).removeClass('open');
$(this).next('.speaker-info').toggleClass('fade');
$('.speaker-info').removeClass('fade');
}
});
$('.close-speaker').on('click', function() {
var container = $(this).closest('.speaker-info').height();
$(this).closest('.speaker-container').css({'height' : container}).removeClass('open');
$('.speaker-info').removeClass('fade');
});

I suggest you can use JQuery for that feature you want to do. Here's the link for your reference: JQuery Accordion. I hope it helps. Thanks!

Related

Javascript detect if hover is on bottom or top padding of element

I know it might sound like a weird question but I have some items in a list with the following HTML:
<div class="list-cards">
<div class="list-item">
<a class="list-card" draggable="true">item</a>
</div>
<div class="list-item">
<a class="list-card" draggable="true">item</a>
</div>
<div class="list-item">
<a class="list-card" draggable="true">item</a>
</div>
</div>
CSS:
.list-item {
padding: 4px 0px;
}
.list-cards = my list
.list-item = 1 list-item
.list-card = simply the style and text of an item (not important for this question)
Now I want to detect whether, when hovering, I'm hovering on the padding-top of my list-item div or on the padding-bottom. (maybe there is a way to get the full height of my item and then use some kind of mouse coordinate to know my 'height' (=position of mouse)? If there is then I have no idea how to do this
For backstory: I'm making some kind of drag & drop to-do list as a project. I can drag my items between x amount of lists but I always just append the item to the bottom of the list. Now I want to use the padding of my list-item to check if I'm above or below an item
If I know that I can add the item that I'm dragging around either above or below an item depending on where I released my mouse button
I would prefer a solution using vanilla javascript but if jQuery is required then that's fine too. Other frameworks/libraries I'd prefer not to touch
Once again, thanks in advance
You can do something like the following, adapt to your code as needed
it takes the offset of the target element and compares that to the location of the event. If the event is in the top half of the target element it records above, else below.
$('.list-item').hover(function(e) {
var offset = $(this).offset().top;
var this_height = $(this).height();
var Y = e.pageY;
var loc = Math.abs(offset - Y);
if (loc < this_height/2) {
console.log('above');
}
else {
console.log('below');
}
})

What is a more efficient way of checking for width when using the jQuery UI resizable tool?

I am making a site with a resizable sidebar. When the user resizes this sidebar, I would like the icons and text in the sidebar to shrink with the sidebar. Currently I am using if statement to check if the sidebar's width is below a certain size, but when I look on my Mac's Activity Monitor it shows that there is a lot of strain going on in Chrome when I continually resize the sidebar. My solution works, but I was wondering if there was a more efficient way to go about this. This is what I'm working with:
HTML:
<div id = "home_left">
<img src="images/image1.jpg" id = "profile_picture"/>
<p id = "profile_username">username</p>
<div class = "icon_container">
<img src="images/image2.png" class = "profile_icons"/>
</div>
<div class = "icon_container">
<img src="images/image3.png" class = "profile_icons"/>
</div>
<div class = "icon_container">
<img src="images/image4.png" class = "profile_icons"/>
</div>
</div>
jQuery:
$(document).ready(function(){
// Setting the left sidebar as resizable
$("#home_left").resizable({
handles: "e",
maxWidth: $("#home_left").width(),
minWidth: 100,
resize: function() {
//Width of profile picture
$("#profile_picture").width($("#home_left").width() - 24);
//Appearance of username and icons
if($("#home_left").width() < 200) {
$("#profile_username").addClass("hidden");
$(".icon_container").width($("#home_left").width());
}
else {
$("#profile_username").removeClass("hidden");
}
}
});
});
Fiddle: https://jsfiddle.net/mpjb19m7/
It doesn't show as much CPU usage in the Fiddle because there are no images being resized, but you can still see that there is a great deal more strain on the browser than usual. Is this just how jQuery UI is or am I doing something inefficiently?
If you check the Resizable Widget API, you will notice that you can bind callbacks not only for the resize event (which I guess it's the source of the strain you notice, since that's gonna fire continuously) but also for start and stop events.
I guess listening for those events can solve your problem, if you need your sidebar UI to be responding only on the begin/end of a resize operation.

javascript picture change not working correctly

Im in the middle of creating a site and have run into a bit of an issue. Basically what im working with is a collection of 3 pictures, two small, one large. What I'd like is that when you click one of the small pictures, it takes the spot of the larger picture. I have a javascript function that does this successfully but with one minor issue. Theres 3 of these collections of 3 pictures and thus when you click a small image to have it swap with the bigger one, the small image takes the spot of all of all 3 of the larger images instead of just the one for its section. Any suggestions? Thanks
the javascript function
$(document).ready(function(){
$('img').click(function(){
var url = $(this).attr('src');
var bigUrl = $(this).parents('.picture-container').find('.large-picture > img').attr('src');
$('.large-picture > img').attr('src', url);
$(this).attr('src', bigUrl);
});
});
what one of the sections looks like
<div class = 'main-content'>
<div class = 'picture-container'>
<div class = 'large-picture' style = 'width:50%;height:100%;float:left;'>
<img src = 'close_table_dupontstudios.png' width = '100%' height = '100%'>
</div>
<div class = 'picture-content' style = 'float:right;width:45%;height:100%;'>
<div class='picture-title'>BOUTIQUE PRODUCTION STUDIO</div>
<div class='picture-text'>We built a boutique full service production studio that allows for one, two and three person filmed interviews and conversations. We have studio lights, a three camera set-up and remote monitoring. Additionally, our Infinity Wall creates a clean and professional look that allows the film to be about the message.</div>
<div class = 'small-picture-wrapper'>
<div class = 'small-picture' style = 'float:left;height:100%;'>
<img src = 'hair_and_makeup_dupontstudios.png' width = '100%' height = '100%'>
</div>
<div class = 'small-picture' style = 'float:right;height:100%;'>
<img src = 'infinity_wall_dupontstudios.png' width = '100%' height = '100%'>
</div>
</div>
</div>
</div>
You're using a class selector for .large-picture when you're selecting it to apply the new image src. Presumably, all three sections have an element with this class, meaning all three are selected by your .large-picture selector. You need a more explicit selector to get ONLY the appropriate element.
You could use an id, or you could use parents() and find() in conjunction like you did previously:
$(this).parents('.picture-container').find('.large-picture > img').attr('src', url);

Is there a way to have hidden content of a page slide UP into page? jQuery / JavaScript

Basically, this is what I'm trying to do. I have content, a form, a the bottom of my page, with its display set to none. What I want to do, is when someone clicks an up arrow, the image icon, the whole form will slide UP into view, and become visible, while if they click the arrow again, it will return the form to slide back down and also set its display back to none. This is what I have so far.
<div class="hidden_panel_wrapper">
<div class="hidden_panel_icon"> <img id="hidden_panel_icon" src="thumbnails/up_arrow.png"> </div>
<div class="hidden_panel hide" id="hidden_panel">
<div class="hidden_panel_form">
<form name="newsletter_subscribe" method="post" action="subscribe_success.php">
<input class="text_input" type="email" placeholder="Type E-Mail Address" name="email">
<input type="submit" class="button_input" value="Subscribe To Our Newsletter">
</form>
</div>
</div>
</div>
So I know that to use slide toggle, slidedown will bring elements into view, but i cant figure out how to slideUP and bring an element into view. I looked around at jquery animate, couldn't really figured it out, and i also just looked at setting new styles via javascript (object.style.top="-200px" but that didnt really work. To be simple, I need a slidetoggle, but so it my content will slide UP into view, and DOWN back to display="none". Thanks in advance!
I believe this is what you are wanting. http://jsfiddle.net/bR6Fs/
$(document).ready(function(e) {
$(".caption").hide();
});
var show = function() {
$(".caption").slideUp(500);
};
var hide = function() {
$(".caption").slideDown(500);
};
$(".featured-image").hover(hide, show);
jQuery animate plus some creativity should work. You'll have to tweak some parts of this based on the kind of animation you want and what you know about where you want it to go, but the framework should work.
The script:
//get height of window
var windowHeight = $(window).height();
//difference between window height and desired distance from top, e.g. 200px
var moveDistance = windowHeight - 200;
$('.hidden_panel_wrapper').css({'top' : moveDistance+'px', 'display' : 'block'});
$('.hidden_panel_wrapper').animate({top:0});
Then to slide it out it's basically the reverse:
//get height of window
var windowHeight = $(window).height();
//difference between window height and desired distance from top, e.g. 200px
var moveDistance = windowHeight - 200;
$('.hidden_panel_wrapper').animate({top:moveDistance}).css('display' : 'none');
That said, there are a number of jQuery addons that you can Google for if you're going to be doing a lot of animation and want a bigger toolkit for prebuilt functions.

Div is jumpy with fadeIn jQuery

When I roll over .comptext_rollover div it should hide the initial div on the page and show the minipage div. but it does but is sometimes really jumpy and also the minipage div sometimes shows below the initialpage div. any ideas? sorry i am new to coding! Thanks in advance.
$(document).ready(function() {
$('#mini_page').hide();
$('.comptext_rollover').hover(function() {
$('#initial_page').hide();
$('.register_button').hide();
$('#mini_page').fadeIn(100);
$('#container').css({
'margin-top': '-217px'
});
}, function() {
$('#mini_page').hide();
$('#initial_page').show();
$('.register_button').show();
$('#container').css({
'margin-top': '-150px'
});
});
});
I prepared a fiddle demo HERE
re-EDIT:
JSFIDDLE DEMO
(the demo may be incorrect while the main CSS is an external link)
I used:
<div id="container">
<div id="initial_page" class="page">
<div id="playvideo_hoverbutton"></div>
<div class="register_button"></div>
<div id="invisible_register2"></div>
<div id="termsandconditionsapplyshort"></div>
</div>
<div id="mini_page" class="page">
<div id="minicar_animated"></div>
<div id="worth25k"></div>
<div class="register_button"></div>
<div id="invisible_register"></div>
</div>
<!-- THE ROLLOVER IS OUT OF ALL 'PAGES'! -->
<div class="comptext_rollover">
<!--<div id="competition_text"></div>-->
</div>
</div>
$('#mini_page').hide();
$('.comptext_rollover').mouseenter(function() {
$('.page').fadeToggle(400);
});
$('.comptext_rollover').mouseleave(function() {
$('.page').fadeToggle(400);
});
In any case what you should do:
Position absolute the 2 screens you need to 'swap' into a container.
Than what you do:
Position the 'rollover' element outside the 'screens'.
Adjust the marginTop of the bigger image(car image) in the CSS (like I did) to fix the buggy 'jumps'.
IF POSSIBLE: ONLY ONE rollover ACTION ELEMENT!
Fix the margin-top of the car image. (give it a -Npx)
Doing so you don't need to do that stuff with positioning your container -Npx
There is also a simpler way to do the same effect:
you add to BOTH screens a class .swappable, making the second one (CSS)display:none; , and than you just use jQuery toggling just this class.
you've not set a great deal of time for the fade in. you're also just hiding some of the divs which makes the fade in move around depending on where you put them. maybe use slides instead. I have saved an example here: http://jsfiddle.net/kBEUH/
$(document).ready(function(){
$('#mini_page').hide();
$('.comptext_rollover').hover(function () {
$('#initial_page').fadeOut(1000);
$('.register_button').fadeOut(1000);
$('#mini_page').slideDown(1000);
}, function(){
$('#mini_page').slideUp(1000);
$('#initial_page').fadeIn(1000);
$('.register_button').fadeIn(1000);
});
});
if you put a console.log in your hover() function, you'll see hover is firing like crazy. This causes the animation to start over and over again, while moving your mouse.
You could take advantage of the jquery :animated selector:
$('.comptext_rollover').hover(function() {
//enable this line to see the hover event is firing every time your mouse moves
//console.log("hovering")
//if the div is in the middle of an animation, do nothing
if (!$("#mini_page").is(":animated")) {
$('#initial_page').hide();
$('.register_button').hide();
$('#mini_page').fadeIn(100);
$('#container').css({
'margin-top': '-217px'
});
}
}, function() {
//etc
});
EDIT:
Now I think of it, your probably want to use .mouseenter() and .mouseleave() instead of hover()
$('.comptext_rollover').mouseenter(function() {
//your code
}).mouseleave(function() {
//your code
});

Categories