I'm trying to make a bar that slides horizontally. If it's positioned left, it will slide right. If it's positioned right, it will slide left. Eventually this will contain multiple bars side by side that will slide out of the way to reveal different images.
right now it would work fine except i can't seem to figure out how to get it to fire more than once. I'm not a javascript guy by any stretch of the imagination, so just a little push in the right direction would be appreciated.
Thanks
Luke
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<script>
var x=1;
$(document).ready(function(){
if( x==1 )
{
x=2;
$("#block").click(function()
{
$("#block").animate({right:'20px'});
});
return;
}
if( x==2 )
{
x=1;
$("#block").click(function()
{
$("#block").animate({left:'20px'});
});
return;
}
});
</script>
</head>
<body>
<p> This block should slide right if it's positioned left, and slide left if it's positioned right. It should repeat this behavior indefinitely. Right now it's being very naughty indeed!</p>
<div id=block style="background:#98bf21;height:100px;width:16px;position:absolute;">
</div>
</body>
</html>
Bind the event out the if statment and put the condition in side event.
Live Demo
$(document).ready(function(){
var x=1;
$("#block").click(function()
{
if( x==1 )
{
x=2;
$("#block").animate({right:'20px'});
}
else
{
x=1;
$("#block").animate({left:'20px'});
}
});
});
To keep the rule cycle you may need to change the code like given below
Live Demo
$(document).ready(function() {
var x = 1;
$("#block").click(function() {
if (x == 1) {
x = 2;
$("#block").animate({
right: '20px',
left: '0px'
});
}
else {
x = 1;
$("#block").animate({
left: '20px',
right: '0px'
});
}
});
});
You cannot easily animate left and right, because jQuery doesn't know the exact end position when you change left: 0 to right: 0. What you can do is calculating this yourself and using left only. Some other things are:
Use a boolean to flip instead of a number
Don't decide what event handler to bind, but decide what should happen when the handler is called
Use $(this) for the current element
http://jsfiddle.net/HZRWJ/
$(document).ready(function(){
var isLeft = true;
$("#block").click(function() {
var fullWidth = $(document).width();
var elemWidth = $(this).width();
if(isLeft) {
$(this).animate({ left: fullWidth - elemWidth });
} else {
$(this).animate({ left: 0 });
}
isLeft = !isLeft;
});
});
Does this do something similar to what you wanted?
Fiddle Demo
$("#block").data('position', 'left');
$("#block").click(function() {
var elem = $(this);
resetElementPosition(elem);
switch (elem.data('position')) {
case 'left': elem.animate({ right: '20px' }); elem.data('position', 'right'); break;
case 'right': elem.animate({ left: '20px' }); elem.data('position', 'left'); break;
}
});
function resetElementPosition(element)
{
element.css({ 'left' : 'auto', 'right' : 'auto' });
}
If you are going to have multiple bars it might be easier to store values in a jQuery object.
$(document).ready(function(){
$("#block").each( function( ) {
// associate data with each element. At the moment there should
// only be one but if this is implemented as a class there may
// be more
$(this).data("x", 0);
});
$("#block").click( function( ) {
// 0 will push it to the right as 0 => false
if( $(this).data("x") ) {
$(this).data("x", 0 );
// removing the css property allows you to use left & right
$(this).css("right","").animate({left:'20px'});
} else {
$(this).data("x", 1 );
$(this).css("left","").animate({right:'20px'});
}
});
});
Demo here
Related
I'm having an issue with this jQuery that is blowing my mind. I've tried three different JS and jQuery functions people suggested online for accomplishing this and can't seem to get anything to work.
I'm trying to hide the class .arrow-up when .first is actually visible on the screen and hide the class .arrow-down when .last is visible on the screen.
Sounds simple enough, right?
Well the parent element has overflow: hidden on it (like most carousels–they really are from hell). Anyone know how to do this? I'd really appreciate any help, JS really isn't my strongest by any means...
Here's my current jQuery–
jQuery(document).ready(function ($) {
$(".arrow-down").bind("click", function (event) {
event.preventDefault();
$(".vid-list-container").stop().animate({
scrollTop: "+=300"
}, 300);
});
$(".arrow-up").bind("click", function (event) {
event.preventDefault();
$(".vid-list-container").stop().animate({
scrollTop: "-=300"
}, 300);
});
});
In this, .vid-list-container is the parent with overflow: hidden on it and .first and .last are both inside the container. The arrow classes are both outside of the container.
Built this pen for anyone who wants to play around with it.
http://codepen.io/seancrater/pen/waPNEW
Thanks!
This should work. Notice however that I used opacity:0, so the arrow can still be clicked. You need to change that!
function checkDownArrow() {
setTimeout(function() {
if($(".vid-list-container").scrollTop() != 0){
$('.arrow-up').css('opacity',1);
}
if(($(".vid-list-container").scrollTop() + $(".vid-item").height()+5) >= $(".vid-item").length * $(".vid-item").height()) {
$('.arrow-down').css('opacity',0);
}
},350);
}
function checkUpArrow() {
setTimeout(function() {
if($(".vid-list-container").scrollTop() == 0){
$('.arrow-up').css('opacity',0);
}
if(($(".vid-list-container").scrollTop() + $(".vid-item").height()+5) < $(".vid-item").length * $(".vid-item").height()) {
$('.arrow-down').css('opacity',1);
}
},350);
}
checkDownArrow();
checkUpArrow();
jQuery(document).ready(function ($) {
$(".arrow-down").bind("click", function (event) {
event.preventDefault();
$(".vid-list-container").stop().animate({
scrollTop: "+=173"
}, 300);
checkDownArrow();
});
$(".arrow-up").bind("click", function (event) {
event.preventDefault();
$(".vid-list-container").stop().animate({
scrollTop: "-=173"
}, 300);
checkUpArrow();
});
});
EDIT
Okay, I see you have a different problem... may I suggest using a different approach? Something like this.
HTML:
<div class="outer-wrapper">
<div class="inner-wrapper">
<div class="vid-item">
...
</div>
<div class="vid-item">
...
</div>
</div>
</div>
CSS:
.outer-wrapper {width:200px; height:150px; overflow:hidden;}
.inner-wrapper {height:auto; margin-top:0;}
.vid-item {width:200px; height:150px;}
JS:
var itemHeight = $('.vid-item').first().height();
var wrapperHeight = $('.inner-container').height();
$(".arrow-down").bind("click", function (event) {
event.preventDefault();
var margin = parseInt($('.inner-container').css('margin-top'));
if(itemHeight - margin > wrapperHeight) {
$('.inner-container').css('margin-top', (itemHeight-wrapperHeight) + 'px');
$('.arrow-down').addClass('hidden');
}
else {
$('.inner-container').css('margin-top', (margin-itemHeight) + 'px');
}
$('.arrow-up').removeClass('hidden');
});
$(".arrow-up").bind("click", function (event) {
event.preventDefault();
var margin = parseInt($('.inner-container').css('margin-top'));
if(margin + itemHeight >= 0) {
$('.inner-container').css('margin-top', '0');
$('.arrow-up').addClass('hidden');
}
else {
$('.inner-container').css('margin-top', (margin+itemHeight) + 'px');
}
$('.arrow-down').removeClass('hidden');
});
I am having an issue with my slideToggle function. Once pressed it opens up the way I need it to. But when I scale the browser to test the responsive flow to the site the slideToggle still stays active instead of sliding down. I tried a few functions but nothing seems to work. Below is the scrip I am using without the code to slide down when it hits a specific screen resoultion. How would I go about fixing this issue?
$('#more').click(function () {
var open = $('header').is('.open');
$('#footerPanel')['slide' + (open ? 'Up' : 'Down')](400);
$('header').animate({
bottom: (open ? '-' : '+') + '=120' }, 400, function () {
$('header').toggleClass('open');
});
});
$('#menu').click(function () {
if ($('header').is('.open')) {
$('header')
.removeClass('open')
.animate({
'bottom': "-=120"
}, function () {
var $footer = $('.activetoggle');
if ($footer.length)
$footer
.toggleClass('activetoggle footerButton')
.text('Footer');
});
$('#footerPanel').slideUp(400);
}
});
$('.footerButton').click(function () {
var $this = $(this);
$this.toggleClass('footerButton');
if ($this.hasClass('footerButton')) {
$this.text('Footer');
} else {
$this.text('Close');
}
$(this).toggleClass('activetoggle');
});
My Code
http://jsfiddle.net/wyze/XqUp4/4/
Try if this works for you. I have added to check whether the width is 780(you can change it), when the panel to slide down. Try adding this in you fiddle and check if this works
$(window).resize(function(){ //check when window resize
if($(window).width() < 780){ // check when the window width is less than 780
if ($('header').is('.open')) {
$('header')
.removeClass('open')
.animate({
'bottom': "-=120"
});
$footer = $('.activetoggle');
if ($footer.length) {
$footer.toggleClass('activetoggle footerButton').text('Footer');
}
$('#footerPanel').slideToggle(400);
}
}
});
I'm using Jquery Collision to detect two objects overlapping each other. Here is a JSFiddle of the problem.
(apologies for including jquery collision script in HTML, couldn't find other way)
Click anywhere in the gray container to move the green div over the white div.
HTML Structure:
<div class="container">
<div class="test"></div>
<div class="menu"></div>
</div>
JS:
$(document).ready(function () {
var hit_list;
$(".container").click(function () {
$(".menu").stop().animate({
left: "+=100px"
}, 300, function () {
$(".menu").animate({
left: "0"
}, 800);
});
//Test for collision
hit_list = $(".menu").collision(".test");
if (hit_list.length != 0) {
alert("welcome Earthling!");
}
});
});
The problem with my method is that, it doesn't detect collision every time. Even though it passes over the white division fine, the alert isn't displayed everytime.
Am I going wrong anywhere in checking for collision? Is there a better/more efficient method to detect collisions during animation ?
jQuery animate has a step callback (https://api.jquery.com/animate/), it gets executed after each step of the animation.
Use it like this:
$(document).ready(function () {
var hit_list;
$(".container").click(function () {
$(".menu").stop().animate({
left: "+=100px"
}, {
duration: 300,
complete: function () {
$(".menu").animate({
left: "0"
}, 800);
},
step: function(){
//Test for collision
hit_list = $(".menu").collision(".test");
if (hit_list.length != 0) {
alert("welcome Earthling!");
}
}
});
});
});
Try this http://jsfiddle.net/aamir/y7PEp/6/
$(document).ready(function () {
var hit_list;
var hits=0;
$(".container").click(function () {
var $this = $(this);
function checkCollision() {
//Test for collision
hit_list = $(".menu").collision(".test");
if (hit_list.length != 0) {
hits++;
$(".menu").html(hits+ ' hits');
}
}
$(".menu").stop().animate({
left: "100px"
}, 300, function () {
checkCollision();
$(".menu").animate({
left: "0"
}, 800);
});
});
});
I have spent last 2 days working on a front page to a new website but these one functionality I cant get to work.
It's probably best to view this link.
http://isca01.bigwavemedia.info/~stagedgo/html/
When you hover on promotions the page pushes 20px to the left, but when the slider is pushed clicked, when you hover over it again it should push 20 px to the right.
I used the code bellow, the way it works it checks if the wrapper has been pushed.
if ($('.wrapper').css('marginLeft') == "0px") {
//code to push page left 20
}
if ($('.wrapper').css('marginLeft') > "1px") {
//code to push page right 20
}
Any help would be amazing, thanks.
As an update to what Eugene said, you should be able to use this:
if (parseInt($('.wrapper').css('margin-left').replace('px', '')) == 0) {
//code to push page left 20
}
if (parseInt($('.wrapper').css('margin-left').replace('px', '')) >= 20) {
//code to push page right 20
}
This'll ensure the value returned is an integer and that you're actually getting the value of the left-margin instead of 'marginLeft' which isn't a valid attribute.
EDIT: just noticed I missed a closing bracket but the code works for me. I've made a test on jsfiddle here (just change the margin-left value to appropriate values to see the box change colour)
You can't use the "more than" operator on something that is not a number.
Try this:
if ($('.wrapper').css('marginLeft') == "0px") {
//code to push page left 20
} else {
//code to push page right 20
}
Alternatively, you can just pass the numbers without "px" to compare:
if (parseInt($('.wrapper').css('marginLeft')) == 0) {
//code to push page left 20
}
if (parseInt($('.wrapper').css('marginLeft')) >= 20) {
//code to push page right 20
}
Edit:
Replace your whole hovering code (from line 200 to line 243) with this. Basically, move it minus to the right when margin is 0, and minus to the left when the margin is not 0. This should solve your problem.
$(".show_hide").hover(function() {
if(parseInt($(".wrapper").css('marginLeft')) == 0) {
$(".wrapper").animate({
right: -20,
opacity: 1
}, 300);
} else {
$(".wrapper").animate({
left: -20,
opacity: 1
}, 300);
};
}, function() {
$(".wrapper").animate({
right: 0,
left: 0,
opacity: 1
}, 300);
});
Your JavaScript code is:
$(document).ready(function(){
// some code here
$('.show_hide').toggle(function(){
// some code here
},
function() {
// some code here
});
if ($('.wrapper').css('marginLeft') == "0px") {
$(".show_hide").hover(function () {
$(".wrapper").animate({ left: 20, opacity : 1 }, 300);
},
function () {
$(".wrapper").animate({ left:0, opacity : 1 }, 300);
})
}
else if ($('.wrapper').css('marginLeft') > "1px") {
$(".show_hide").hover(function () {
$(".wrapper").animate({ right:20, opacity : 1 },300);
},
function () {
$(".wrapper").animate({ right:0, opacity : 1}, 300);
})
}
});
What you can see here, is that you define the 'hover' behaviour once when the document is ready.
Whereas what you should do is redefine this behaviour during the 'toggle' event.
I propose you use this code instead:
function setupHoverBehaviour() {
var marginValue = $('.wrapper').css('marginLeft');
if ( marginValue == "auto" || parseInt(marginValue) == "0" ) {
$(".show_hide").hover(function () {
$(".wrapper").animate({ left: 20, opacity : 1 }, 300);
},
function () {
$(".wrapper").animate({ left:0, opacity : 1 }, 300);
})
}
else {
$(".show_hide").hover(function () {
$(".wrapper").animate({ right:20, opacity : 1 },300);
},
function () {
$(".wrapper").animate({ right:0, opacity : 1}, 300);
})
}
}
$(document).ready(function(){
// some code here
$('.show_hide').toggle(function(){
// some code here
setupHoverBehaviour();
},
function() {
// some code here
setupHoverBehaviour();
});
setupHoverBehaviour();
});
I would add a class to the wrapper or the trigger element on the click event to indicate that it had been pushed. Then you can use .hasClass("pushed") on whichever element to determine if it needs to slide left or right.
I am trying to make a carousel of sorts. I am kind of stuck with hiding and displaying the next and precious buttons once a div moves to the far left and right of its container.
I think i have everything correct regarding calculating the widths but for some reason when you click the buttons, elements stay hidden irrespective of the conditional comments which should dictate when they should be hidden or shown.
Here is a link to what i have thus far. Click the MoveLeft and MoveRight buttons. http://www.ehbeat.com/test/
<script type="text/javascript">
$(document).ready(function () {
//Check width of Gallery div
var galleryWidth = $("#Gallery").innerWidth();
//Check width of GalleryItem
var galleryItemWidth = $(".GalleryItem").innerWidth();
//Check distance from left
var position = $('.GalleryItem').position();
var galleryItemLeft = position.left;
$(".MoveRight").click(function () {
$(".GalleryItem").animate({
"left": "+=50px"
}, "slow");
$(".GalleryItem2").animate({
"left": "+=100px"
}, "slow");
});
$(".MoveLeft").click(function () {
$(".GalleryItem").animate({
"left": "-=50px"
}, "slow");
$(".GalleryItem2").animate({
"left": "-=100px"
}, "slow");
});
$(".Controls").live('click', function () {
if (galleryItemLeft >= "0") {
$('.MoveRight').hide();
}
else {
$('.MoveRight').show();
}
});
if (galleryItemWidth == galleryWidth - galleryItemWidth) {
$('.MoveLeft').hide();
}
});
</script>
It looks like you setup all of your variables inside the $(document).ready() call.
This means that while they're being set on load, they're not getting updated with each click.
Your galleryItemLeft, galleryItemWidth and galleryItemWidth variables need to be updated on each click, so I'd recommend re-assigning the values in each click (by moving the assignment into the live functions)
Edit Also, as your last if statement is excluded from any click function, it'll need to be relocated to inside the live click events as well.
-Chris
Chris is right, code should look like this:
$(".Controls").live('click', function() {
position = $('.GalleryItem').position();
galleryItemLeft = position.left;
if(galleryItemLeft > "0") {
$('.MoveRight').hide();}
else{
$('.MoveRight').show();
}
if(galleryItemWidth == galleryWidth - galleryItemWidth) {
$('.MoveLeft').hide();
}
});