Sliding Panels with JavaScript - javascript

This example I've found is exactly what I was looking for: http://jsfiddle.net/sg3s/RZpbK/
Thx to the author sg3s
jQuery(function($) {
$('a.panel').click(function() {
var $target = $($(this).attr('href')),
$other = $target.siblings('.active'),
animIn = function () {
$target.addClass('active').show().css({
right: -($target.width())
}).animate({
left: 0
}, 500);
};
if (!$target.hasClass('active') && $other.length > 0) {
$other.each(function(index, self) {
var $this = $(this);
$this.removeClass('active').animate({
left: -$this.width()
}, 500, animIn);
});
} else if (!$target.hasClass('active')) {
animIn();
}
});
});
But I got a little problem with it. I would like the panels to "open" and "close" from the right. I'm not familiar with javascript and I'm not able to tweak it properly.
Can anyone help me with this ?

Like this?
http://jsfiddle.net/RZpbK/845/
All I did was modify the animIn to:
animIn = function () {
$target.addClass('active').show().css({
left: +($target.width())
}).animate({
left: 0
}, 500);
};

Just replace the left: -($target.width()) with left: $target.width() in both places

Based on your previous comment, this is more what you want?
http://jsfiddle.net/RZpbK/847/
Just changed it so animIn executed right away instead of as a callback after the fadeout was done.
$this.removeClass('active').animate({
left: -$this.width()
}, 500);
animIn();

Related

slide right from left with jquery

I'm using this fiddle for a my project but I want to make targets slide from right to left. If you check the link link you can see the targets divs are sliding form left to right.
jQuery(function ($) {
$('a.panel').click(function () {
var $target = $($(this).attr('href')),
$other = $target.siblings('.active');
if (!$target.hasClass('active')) {
$other.each(function (index, self) {
var $this = $(this);
$this.removeClass('active').animate({
left: $this.width()
}, 500);
});
$target.addClass('active').show().css({
left: -($target.width())
}).animate({
left: 0
}, 500);
}
});
});
http://jsfiddle.net/sg3s/rs2QK/ here is a demo.
Please help I really appreciate it.
The only quick and dirty option I found was to play with zIndex and reposition non-active elements with right when animation completes.
jQuery(function($) {
$('a.panel').click(function(e) {
e.preventDefault();
var $target = $($(this).attr('href')),
$other = $target.siblings('.panel');
if (!$target.hasClass('active')) {
$other.css({zIndex: 1});
$target.addClass('active').show().css({
right: -$target.width(),
zIndex: 2
}).animate({
right: 0
}, 500, function() {
$other.removeClass('active').css({
right: -$other.first().width()
});
});
}
});
});
Another way to filter siblings is:
var href = $(this).attr('href');
var idStr = href.replace(/[#\d]+/g, ''); // = 'target'
var $other = $target.siblings("[id^='" + idStr + "']"); // siblings with id that starts with 'target'
-Updated fiddle-

What can I do to simulate Position:Sticky?

If you do not know what position:sticky is, watch this 20 second long video: https://www.youtube.com/watch?v=jA67eda5i-A .
This CSS feature was in talks in W3 and implemented in gecko I believe. But that is besides the point, the point is that not all browsers support it and I really want that functionality.
Is there any way I can get this using a mix of CSS and/or javascript and/or jquery?
There is an easy jquery plugin for this:: http://stickyjs.com/
To avoid using a plugin, i have created the following javascript method using jquery 1.8+.
The first argument is the element that you want to set sticky.
The second argument is optionnal and is a boolean to enhance the browser performance by setting a small timeout of 300ms.
function simulateSticky(elt, timeout) {
var move = function() {
var scrollTop = $(window).scrollTop();
var scrollBottom = $(document).height() - scrollTop - $(window).height();
var eltTop = elt.parent().offset().top;
var eltBottom = $(document).height() - eltTop - elt.parent().outerHeight();
if (scrollTop < eltTop) { // Top case
elt.css({
position: "absolute",
width: "100%",
top:"auto",
right: "0px",
bottom: "auto",
left: "0px",
});
}
else if (scrollTop >= eltTop && scrollBottom >= eltBottom) { // Middle case
elt.css({
position: "fixed",
width: elt.parent().outerWidth(),
top:"0px",
right: "auto",
bottom: "auto",
left: "auto",
});
}
else { // Bottom case
elt.css({
position: "absolute",
width: "100%",
top:"auto",
right: "0px",
bottom: "0px",
left: "0px",
});
}
};
// Use of a timeout for better performance
if (timeout) {
var timeoutId;
$(window).scroll(function() {
clearTimeout(timeoutId);
timeoutId = setTimeout(function() {
move();
}, 300);
});
}
else {
$(window).scroll(move);
}
// Initial call
move();
}

Script does not enter in else statement

I have a table on the right of my page( with id="efficacia"). I wrote this JS script in order to shift left/right clicking on it
JavaScript
$("#efficacia").click(function() {
var posizione = $("#efficacia").position();
if(posizione.right != 0) {
$(this).animate({
right: '0'
}, 1000);
} else {
$(this).animate({
right: '-202'
}, 1000);
}
});
CSS
#efficacia {
position: fixed;
right: -202px;
top: 200px;
cursor: pointer;
z-index: 100;
}
My script works well for the first "click", then when I click again it does not shitf on the right of 202px. It looks like that function does not enter in else statemet.
position().right does not exist. Only top and left.
http://api.jquery.com/position/
Base your condition on left attribute and it will work
position doesn't return a right property.
You can get the right css property so:
$("#efficacia").click(function() {
var right = parseInt($(this).css('right'));
if(right != 0) {
$(this).animate({
right: '0'
}, 1000);
} else {
$(this).animate({
right: '202'
}, 1000);
}
});
See the DEMO.
If you want get position of all corners then you can use getBoundingClientRect(). It will returns bottom, right, left, top, width and height of your div. But, of course, it will return values that starts from left corner.
var boundingBox = $(this).get(0).getBoundingClientRect();
console.log(boundingBox.right);
Read about getBoundingClientRect()
There's an error in your code at right: '-202'. You have to specify right: '-202px'.
Here's the updated code:
$("#efficacia").click(function() {
var right = $(this).css('right');
if(right != "0px") {
$(this).animate({
right: '0px'
}, 1000);
} else {
$(this).animate({
right: '-202px'
}, 1000);
}
});
That's it
jQuery.position() doesn't return value for style.right. It returns only
Object{top: somVal, left: somVal}
so if u want to get the value of right then get it from style attribute
Eg-
$("#efficacia").click(function() {
// var posizione = $("#efficacia").position();//here right is undefined
var right=this.style.right.replace("px", "") * 1;//fetch value of right from style
if(right != 0) {
$(this).animate({
right: '0'
}, 1000);
} else {
$(this).animate({
right: '202'
}, 1000);
}
});

Convert click code to hover code

How can I change the following menu code to open/close when the mouse hovers, instead of when it is clicked on?
var w = 0;
$('.slide').children().each(function () {
w += $(this).outerWidth();
});
$('.outer').width(w + 5);
$('.wrap').width(w);
$('.slide').css('left', w);
$('.open').toggle(function () {
$('.slide').stop().animate({
left: 0
});
$(this).html('close');
}, function () {
$('.slide').stop().animate({
left: w
});
$(this).html('open');
});
Please check this Demo
In Fiddle, you can see the animation works on click. I need to make it work on hover. Can you help with this ?
Use .hover() api
Try this
$('.open').hover(function () {
instead of
$('.open').toggle(function () {
Just
$('.open').toggle(function() {
$('.slide').stop().animate({
left: 0
});
$(this).html('close');
}
in this part just replace toggle with hover
Try using $('.wrap').hover. If $('.open').hover, you will not able to click the nav items.
Also, you can create another wrapper to just wrap div.outer and a.open only
$('.wrap').hover(function() {
$('.slide').stop().animate({
left : 0
});
//this is the .wrap right now
$(this).find('a.open').html('close');
}, function() {
$('.slide').stop().animate({
left : w
});
//this is the .wrap right now
$(this).find('a.open').html('open');
});
http://jsfiddle.net/rooseve/42sWB/2/
$('.open').on('mouseenter mouseleave', function(e) {
if(e.type === 'mouseleave') {
$('.slide').stop().animate({
left: w
});
$(this).html('open');
} else {
$('.slide').stop().animate({
left: 0
});
$(this).html('close');
}
});
var w = 0;
var isVisible = false;
$('.slide').children().each(function() {
w += $(this).outerWidth();
});
$('.outer').width(w+5);
$('.wrap').width(w);
$('.slide').css('left', w);
$('.open').on("mouseover", function() {
if(isVisible == false) {
$('.slide').stop().animate({
left: 0
});
$(this).html('close');
isVisible = true;
}
else {
$('.slide').stop().animate({
left: w
});
$(this).html('open');
isVisible = false;
}
});
Firstly, when you hover the element - the div will be visible, until you hover the element for the second time.
Demo: http://jsfiddle.net/42sWB/3/

Disable click event until animation completes

In my game I have a grid populated with words. To spell the words the user has to click on the letters on the side called "drag". When a letter is clicked it animates into position on the grid.
The problem I am having is that the user can click letters rapidly, which crashes the program. To solve this I want to disable the click events until the animation completes.
In the past I have used a setTimeOut function before but it is not a reliable method as the timing all depends on browser speeds.
Here is the click event:
$('.drag').on('click', function (e) {
e.preventDefault();
var target = $('.highlight-problem .drop-box:not(.occupied):first');
var targetPos = target.parents('td').position();
console.log(targetPos);
var currentPos = $(this).offset();
var b = $(this);
if (target.length) {
target.addClass("occupied");
$(".occupied").parent(".flip-wrapper").addClass("flipped");
var clonedObject = b.clone()
if (b.data("letter") == target.parents('td').data("letter")) {
clonedObject.addClass("right-letter");
target.addClass('right-letter');
setTimeout(function () {
hitSound.play();
}, 550);
} else {
clonedObject.addClass("wrong-letter");
target.addClass('wrong-letter');
setTimeout(function () {
missSound.play();
}, 550);
}
clonedObject.appendTo("table").css({
position: "absolute",
top: currentPos.top,
left: currentPos.left
}).stop().animate({
top: targetPos.top,
left: targetPos.left
}, "slow", function () {
$(this).prop('disabled', false).css({
top: 0,
left: 0
}).appendTo(target);
var spellWord = $('.highlight-problem .drop-box');
if (!spellWord.filter(':not(.occupied)').length) {
var wordIsCorrect = 0;
spellWord.each(function () {
if ($(this).parents('td').data("letter") == $(this).find("div").data("letter")) {
console.log('letter is: ' + $(this).find("div").data("letter"))
wordIsCorrect++;
}
});
You can do it in simple 3 steps.
Declare a global variable called animationComplete and set it to false.
var animationComplete = false;
In your .animate({...}); function, toggle the value after the animation is complete.
.animate({
top: targetPos.top,
left: targetPos.left
}, "slow", function () {
...
animationComplete = true;
});
Check for the completeness using the global variable.
if (animationComplete)
{
// Do something!
}
Full Code
JavaScript
animationComplete = true;
$(document).ready(function(){
animationComplete = false;
$(".background").animate({
height: 50,
width: 50
}, 10000, function(){
animationComplete = true;
});
$("button").click(function(){
if (animationComplete)
$(".background").animate({
height: 200,
width: 200
}, 10000, function(){
animationComplete = false;
});
else
alert("Please wait till the animation is complete!");
});
});
HTML
<div class="background"></div>
<button>Click me!</button>​
CSS
.background {background: red;}
Fiddle: http://jsfiddle.net/KAryP/
Fiddle for your code here: http://jsfiddle.net/smilburn/Dxxmh/94/
Can't test code atm, but checking if the element is not animated within click function should do
if(!$('selector:animated')){
}

Categories