How to use .toggle() method but not for show and hide purposes?
For example, when I click on a certain div I would like to animate it's position
$(div).animate({"left":"+=50px"}); and then on the second click to return the div on the same position $(div).animate({"left":"-=50px"}).
I know there is other solution but I would like to achieve this with .toggle() without hiding an showing the div. Any ideas?
$("#myDiv").toggle(function() {
$(this).stop().animate({
left:"+=50"
}, 500);
}, function() {
$(this).stop().animate({
left:"-=50"
}, 500);
});
#myDiv{
background-color:black;
width:100px;
height:100px;
position:absolute;
left:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<div id="myDiv"></div>
hope this answer your question. However, jQuery 1.9 and newer do not allow this feature.
there is no toggle function using click since 1.9 . But you can still doing this using two ways:
for more explaination
$(function(){
//basic method
var clicked = false;
$('#mydiv1').click(function(){
if(clicked){
clicked = false;
$(this).animate({"left":"+=50px"});
}else{
clicked=true;
$(this).animate({"left":"-=50px"});
}
});
//create new function like old built-in function
$.fn.clickToggle = function(func1, func2) {
var funcs = [func1, func2];
this.data('toggleclicked', 0);
this.click(function() {
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 2;
});
return this;
};
$('#mydiv2').clickToggle(function(){
$(this).animate({"left":"+=50px"});
}, function(){
$(this).animate({"left":"-=50px"});
});
});
#mydiv1{
background-color: yellow;
width: 50px;
height: 50px;
position: absolute;
left: 100px;
}
#mydiv2{
background-color: blue;
width: 50px;
height: 50px;
position: absolute;
left: 200px;
top: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="mydiv1"></div>
<div id="mydiv2"></div>
</div>
Related
I'm trying to make a very light script for multiple classes class"demo" that can work on my onScrollDown responsive animation.
I don't really understand about writing arrays. but, I believe that if I use document.getElementsByClassName("demo")[i] , i < 0 and some function(i) I can implement it for individual classes. Because I use getBoundingClientRect() instead of fixed value.
So, how can I write it correctly using i as arrays?
Thank you..
Here is my working script :
<script>
var e = document.getElementById("demo");
var rect = e.getBoundingClientRect();
var x = rect.top;
$(window).bind('scroll', function () {
if ($(window).scrollTop() > x-300) {
$('#demo').addClass('animate');
} else {
$('#demo').removeClass('animate');
}
});
</script>
*work only for a single element.
Here is what I'm trying to do, that not working yet
<script>
var e = document.getElementsClassName("test")[i];
var rect = e.getBoundingClientRect();
var x = rect.top;
var i;
for (i = 0; i < e.length; i++) {
$(window).bind('scroll', function (i) {
if ($(window).scrollTop() > x-300) {
$e.addClass('animate');
} else {
$e.removeClass('animate');
}
});
}
</script>
CSS :
<style>
.test {
background:#345;
color:#FFF;
height:2em;
padding:.5em;
top:50px;
margin-top: 100px;
width:100%;
}
.animate {
width: 60px;
}
</style>
HTML
<div style="color: red; margin-bottom: 400px;">(Top!)</div>
<div class="test" id="demo">Menu</div>
<div class="test" id="demo">Menu</div>
<div class="test" id="demo">Menu</div>
<div style="color: red; margin-top: 400px;">(Bottom!)</div>
Okay so I've achieved what you're trying to do. Here are the changes I made:
Used the JQuery each function. This will loop all of the demo elements every time a scroll is detected. There are other ways of looping the elements but because you've already imported JQuery we may as well use it's functions.
Changed #demo to .demo. In other words, I've changed id to class. id should only be used when working with elements that are completely unique. In this case, there are multiple demos so we use class instead.
Final code (as you scroll each element will turn red showing that the animate class has been added:
$(window).on('scroll', function() {
$('.demo').each(function(i, obj) {
var rect = obj.getBoundingClientRect();
var x = rect.top;
if ($(window).scrollTop() > x - 300) {
$(obj).addClass('animate');
} else {
$(obj).removeClass('animate');
}
});
});
.body {
height: 200vh;
background-color: #f1f1f1;
}
.demo {
height: 200px;
width: 100%;
background-color: #f9f9f9;
}
.demo.animate {
background-color: #ff0000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="body">
<div class="demo"></div>
<div class="demo"></div>
<div class="demo"></div>
<div class="demo"></div>
</div>
There are few notes in regards to your code:
In jQuery you can get elements offset by using .offset() function.
you should not use the same id more than once per page.
.bind() has been deprecated since jQuery 3.0. Use .on() instead.
To toggle class you can use .toggleClass(className, state). State is used to determine if you want to remove or add the class.
See this example:
$(window).on('scroll', function() {
jQuery(".test").each(function() {
let isTop = $(window).scrollTop() > jQuery(this).offset().top - 300;
jQuery(this).toggleClass('animate', isTop);
});
});
.test {
background: #345;
color: #FFF;
height: 2em;
padding: .5em;
top: 50px;
margin-top: 100px;
width: 100%;
}
.animate {
width: 60px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="color: red; margin-bottom: 400px;">(Top!)</div>
<div class="test">Menu</div>
<div class="test">Menu</div>
<div class="test">Menu</div>
<div style="color: red; margin-top: 400px;">(Bottom!)</div>
I have an object and when I click the button it moves 250px.
$(document).ready(function(){
$("#jqueryAirlinesBut").click(function(){
$("#flyingDroneImage").animate({right: '250px'});
});
});
Now when I click the button again I want it to move 250px back to where it was. I am new to jQuery and it seems like there are no if statements in that language? So what do I do this?
You should use a boolean variable to be able to track which click you're on.
See the example in the snippet.
$(document).ready(function() {
var firstClick = false;
$("#jqueryAirlinesBut").on('click', function() {
if (!firstClick) {
$("#flyingDroneImage").animate({
left: '+=250px'
});
firstClick = true;
} else {
$("#flyingDroneImage").animate({
left: '-=250px'
});
firstClick = false;
}
});
});
#flyingDroneImage {
width: 30px;
height: 30px;
background-color: blue;
position: absolute;
top: 50%;
left: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="jqueryAirlinesBut">Move</button>
<div id="flyingDroneImage"></div>
Why not just use a variable to manage state? Something like this:
var isClicked = false;
$(document).ready(function(){
$("#jqueryAirlinesBut").click(function(){
if(!isClicked){
$("#flyingDroneImage").animate({right: '250px'});
isClicked = true;
} else {
$("#flyingDroneImage").animate({right: '0px'});
isClicked = false;
}
});
});
Here is an Example which may help you:
$(document).ready(function(){
var moved=false;
$("button").click(function(){
if(moved===false){
$("div").animate({'margin-left': '250px'});
moved=true;
}else{
$("div").animate({'margin-left': '0'});
moved=false;
}
});
});
div{
width:50px;
height:50px;
background:#000;
margin-top:20px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Move</button>
<div></div>
save your state
$(document).ready(function(){
// save state
var isLeft = true;
// have a function that responds to state
var goTheOtherWay = function() {
var r;
if (isLeft) {
r = {left: '250px'};
} else {
r = {left: 0};
}
isLeft = !isLeft;
return r;
};
$("#jqueryAirlinesBut").click(function() {
// pass in your state-aware function to $.animate()
$("#flyingDroneImage").animate(goTheOtherWay());
});
});
#canvas {
postiion: absolute;
}
#flyingDroneImage {
background-image: url('http://rotorfx.com/wp-content/uploads/2015/12/large_large-3.jpg');
width: 150px;
height: 150px;
border: 1px solid gray;
background-size: 100%;
background-repeat: no-repeat;
background-position-y: 50%;
float: left;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="jqueryAirlinesBut">jqueryAirlinesBut</button>
<div id="canvas">
<div id="flyingDroneImage"></div>
</div>
$(document).ready(function(){
$("#jqueryAirlineBut").click(function(){
( $("#flyingDroneIMage").css('left') === '0px') ?
$("#flyingDroneIMage").animate({left: '250px'}) : $("#flyingDroneIMage").animate({left: '0px'});
});
});
#flyingDroneIMage{
position:relative;
right:0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<input type="submit" id="jqueryAirlineBut" value="Click to move"/>
<image id="flyingDroneIMage" src="http://lorempixel.com/400/200"/>
Something like this:
$(document).ready(function() {
var toggler = true; //keeps track of where to move
$("#jqueryAirlinesBut").click(function() {
$('#flyingDroneImage').animate({
right: toggler ? '-=250' : '+=250' //decides where to move based on the toggler
}, function() {
toggler = toggler ? false : true //switches the toggler
});
});
});
right: toggler ? '-=250' : '+=250'
The above is a ternary conditional operation.
It means: change the right property based on the following: if the toggler is true, the right property will have 250 pixels subtracted from the current right property, otherwise it will have 250 pixels added to it.
It could be written as
var amountToChange;
if(toggler == true){
amountToChange = '+=250'; //Adds 250 to the existing property
}else{
amountToChange = '-=250'; //Subtracts 250 from the existing property
}
The last function is a callback function, it gets called automatically when the animation finishes its last frame. You can also write that function somewhere else and pass it as the callback, and it will be executed when the animation ends.
You can read about it in the jQuery.animate documentation, it's the complete section
I'm not great with JS so been using trial and error to try and figure out how to get 2 divs to swap z-index on the click of a trigger (button).
I currently have 2 drawers that technically are on top of each other and slide out from the right. On click of 'Buy' the #QuickShopDrawer should open and on click of 'Cart' or 'Add to Cart' the #CartDrawer should open.
Link to my test store.
My code so far is making the open with the #CartDrawer on top with a higher z-index.
JS:
Drawer.prototype.init = function () {
$(this.config.open).on('click', $.proxy(this.open, this));
$('.js-drawer-open-right-two').click(function(){
$(this).data('clicked', true);
});
if($('.js-drawer-open-right-two').data('clicked')) {
//clicked element, do-some-stuff
$('#QuickShopDrawer').css('z-index', '999');
} else {
//run function 2
$('#CartDrawer').css('z-index', '999');
}
this.$drawer.find(this.config.close).on('click', $.proxy(this.close, this));
};
I've tried this which is more of what I want but it's only firing once?
$('.js-drawer-open-right-two').click(function() {
var i = $(this).index();
$('.drawer--right').hide();
$('.drawer--right-two' + (i+1)).show();
});
Any help would be greatly appreciated!
You need to swap the z-index of the elements on button click. Also, you can disable the button on click so that user cannot click it continiously.
Demo
$(document).ready(function() {
$('#buy').on('click', function(e) {
var myZindex = $('#QuickShopDrawer').css('z-index');
$('#QuickShopDrawer').css('z-index', $('#CartDrawer').css('z-index'));
$('#CartDrawer').css('z-index', myZindex);
$(this).prop('disabled', true).siblings('button').prop('disabled', false);
});
$('#addToCart').on('click', function(e) {
var myZindex = $('#CartDrawer').css('z-index');
$('#CartDrawer').css('z-index', $('#QuickShopDrawer').css('z-index'));
$('#QuickShopDrawer').css('z-index', myZindex);
$(this).prop('disabled', true).siblings('button').prop('disabled', false);
});
});
button {
position: absolute;
top: 150px;
left: 0;
clear: both;
}
#addToCart {
margin-left: 50px;
}
.red {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
left: 20px;
top: 20px;
z-index: 1;
}
.green {
position: absolute;
width: 100px;
height: 100px;
background-color: green;
z-index: 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div>
<div id="QuickShopDrawer" class="red">fdsafdsafdsa</div>
<div id="CartDrawer" class="green">fdsafdsafdsa</div>
</div>
<button id="buy">Buy</button>
<button id="addToCart">Add To Cart</button>
I have the following in the tags of the header in my wordpress theme, but no matter what it will not work.
<script>JQuery(function() {JQuery('#fader img:not(:first)').hide();JQuery('#fader img').css('position', 'absolute');JQuery('#fader img').css('top', '0px');JQuery('#fader img').css('left', '50%');JQuery('#fader img').each(function() {var img = JQuery(this);JQuery('<img>').attr('src', JQuery(this).attr('src')).load(function() {img.css('margin-left', -this.width / 2 + 'px');});});var pause = false;function fadeNext() {JQuery('#fader img').first().fadeOut().appendTo(JQuery('#fader'));JQuery('#fader img').first().fadeIn();}function fadePrev() {JQuery('#fader img').first().fadeOut();JQuery('#fader img').last().prependTo(JQuery('#fader')).fadeIn();}JQuery('#fader, #next').click(function() {fadeNext();});JQuery('#prev').click(function() {fadePrev();});JQuery('#fader, .button').hover(function() {pause = true;},function() {pause = false;});function doRotate() {if(!pause) {fadeNext();}}var rotate = setInterval(doRotate, 2000);});</script>
What a mess right? To show that I have been researching this, a previous answer said to remove all whitespaces and change all $ with JQuery. I want to simply fade between a few images in the fader ID.
I have even made a fade.js file, and included it in the functions file, to no avail.
Here is my CSS...
#fader {
position: relative;
width: 100%;
height: 400px;
}
.button {
background-color: green;
width: 50px;
height: 30px;
font-size: 20px;
line-height: 30px;
text-align: center;
position: absolute;
top: 30px;
}
#next {
right: 100px;
}
#prev {
left: 100px;
}
And my HTML ...
<div id="fader">
<img src="http://dummyimage.com/600x400/000/fff.png&text=Image1"/>
<img src="http://dummyimage.com/200x400/f00/000.jpg&text=Image2"/>
<img src="http://dummyimage.com/100x100/0f0/000.png&text=Image3"/>
<img src="http://dummyimage.com/400x400/0ff/000.gif&text=Image4"/>
<img src="http://dummyimage.com/350x250/ff0/000.png&text=Image5"/>
</div>
Instead of showing one image and fading between the 5 images supplied, it just shows all 5 images at the same time.
I first thought this could be a JQuery problem, so tested to see if JQuery was functioning, which it is.
Here is the original JQuery before I removed whitespaces and swapped $ for JQuery.
$(function() {
$('#fader img:not(:first)').hide();
$('#fader img').css('position', 'absolute');
$('#fader img').css('top', '0px');
$('#fader img').css('left', '50%');
$('#fader img').each(function() {
var img = $(this);
$('<img>').attr('src', $(this).attr('src')).load(function() {
img.css('margin-left', -this.width / 2 + 'px');
});
});
var pause = false;
function fadeNext() {
$('#fader img').first().fadeOut().appendTo($('#fader'));
$('#fader img').first().fadeIn();
}
function fadePrev() {
$('#fader img').first().fadeOut();
$('#fader img').last().prependTo($('#fader')).fadeIn();
}
$('#fader, #next').click(function() {
fadeNext();
});
$('#prev').click(function() {
fadePrev();
});
$('#fader, .button').hover(function() {
pause = true;
},function() {
pause = false;
});
function doRotate() {
if(!pause) {
fadeNext();
}
}
var rotate = setInterval(doRotate, 2000);
});
Thanks in advance!!!!!!!
I love you ;)
Use jQuery or $ and not what you are using.
You are using JQuery, which is wrong.
But if you really want to use JQuery,then you can do the below:
var JQuery = jQuery;
Now, after the assignation, you can use JQuery
I am adapting the Coverflow technique to work with a div. Following is the html:
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style type="text/css" media="screen">
body,html {
margin: 0;
padding: 0;
background: #000;
height: 100%;
color: #eee;
font-family: Arial;
font-size: 10px;
}
div.magnifyme {
height: 80px;
padding: 80px;
position: absolute;
top: 0px;
left: 0px;
width: 2000px;
}
div.wrapper {
margin: 0px;
height: 470px;
/*border: 2px solid #999;*/
overflow: hidden;
padding-left: 40px;
right: 1px;
width: 824px;
position: relative;
}
div.container {position: relative; width: 854px; height: 480px; background: #000; margin: auto;}
div.nav {position: absolute; top: 10px; width: 20%; height: 10%; right: 1px; }
div.magnifyme div {
position: absolute;
width: 300px;
height: 280px;
float: left;
margin: 5px;
position: relative;
border: 2px solid #999;
background: #500;
}
</style>
<script type="text/javascript" src="jquery-1.3.2.js"></script>
<script type="text/javascript" src="ui.coverflow.js"></script>
<script type="text/javascript" src="ui.core.js"></script>
<script type="text/javascript">
$(function() {
$("div.magnifyme").coverflow();
$("#add").click(function() {
$(".magnifyme").append("<div id=\"div5\">hello world</div>");
$("div.magnifyme").coverflow();
});
});
</script>
</head>
<body>
<div class="container">
<div class="wrapper">
<div class="magnifyme">
<div id="div0">This is div 0</div>
<div id="div1">This is div 1</div>
<div id="div2">This is div 2</div>
<div id="div3">This is div 3</div>
<div id="div4">This is div 4</div>
</div>
</div>
<div class="nav">
<button type="button" id="add">Add to Deck</button>
</div>
</div>
</body>
</html>
The coverflow function (included as a js file in the head section) is here. When I click the button, I was expecting it to add a DIV to the already present deck. For some reason, it doesn't show the newly added DIV. I tried calling the coverflow() function after I added the new element but that didn't work either. The modified coverflow function is given here:
;(function($){
$.widget("ui.coverflow", {
init: function() {
var self = this;
this.items = $(this.options.items, this.element).bind("click", function() {
self.moveTo(this);
//$("div.slider").slider("moveTo", self.current, null, true);
});
this.itemWidth = this.items.outerWidth(true);
this.current = 0; //Start item
this.refresh(1, 0, this.current);
this.element.css("left",
(-this.current * this.itemWidth/2)
+ (this.element.parent()[0].offsetWidth/2 - this.itemWidth/2) //Center the items container
- (parseInt(this.element.css("paddingLeft")) || 0) //Subtract the padding of the items container
);
},
moveTo: function(item) {
this.previous = this.current;
this.current = !isNaN(parseInt(item)) ? parseInt(item) : this.items.index(item);
if(this.previous == this.current) return false; //Don't animate when clicking on the same item
var self = this, to = Math.abs(self.previous-self.current) <=1 ? self.previous : self.current+(self.previous < self.current ? -1 : 1);
$.fx.step.coverflow = function(fx) {
self.refresh(fx.now, to, self.current);
};
this.element.stop().animate({
coverflow: 1,
left: (
(-this.current * this.itemWidth/2)
+ (this.element.parent()[0].offsetWidth/2 - this.itemWidth/2) //Center the items container
- (parseInt(this.element.css("paddingLeft")) || 0) //Subtract the padding of the items container
)
}, {
duration: 1000,
easing: "easeOutQuint"
});
/*current = this.current;
$("[id^=div]").each(function() {
if(this.id != "div"+current) {
console.info(this.id + " Current: " + current);
$(this).fadeTo( 'slow', 0.1);
}
});*/
},
refresh: function(state,from,to) {
var self = this, offset = null;
this.items.each(function(i) {
var side = (i == to && from-to < 0 ) || i-to > 0 ? "left" : "right";
var mod = i == to ? (1-state) : ( i == from ? state : 1 );
var before = (i > from && i != to);
$(this).css({
webkitTransform: "matrix(1,"+(mod * (side == "right" ? -0.5 : 0.5))+",0,1,0,0) scale("+(1+((1-mod)*0.5))+")",
left: (
(-i * (self.itemWidth/2))
+ (side == "right"? -self.itemWidth/2 : self.itemWidth/2) * mod //For the space in the middle
),
zIndex: self.items.length + (side == "left" ? to-i : i-to)
});
if(!$.browser.msie)
$(this).css("opacity", 1 - Math.abs((side == "left" ? to-i : i-to))/2);
});
}
});
$.extend($.ui.coverflow, {
defaults: {
items: "> *"
}
});
})(jQuery);
One thing I did notice is that after clicking the button for about 5-10 times, the elements show up but not along with the already present divs but rather below them. I am guessing that this has something to do with the CSS of the magnifyme class (2000px), but I am not sure what it is. Is there any way I can make this work?
You need to write an additional function for the coverflow widget:
add: function(el) {
var self = this;
this.element.append(el)
this.options.items = $('> *', this.element);
this.items = $(this.options.items, this.element).bind("click", function() {
self.moveTo(this);
});
this.itemWidth = this.items.outerWidth(true);
this.moveTo(this.items.length-1);
},
and then call it like so:
$("#add").click(function() {
$("div.magnifyme").coverflow('add', "<div></div>");
});
First, you need to add a references to the jQuery UI core, and it also appears that it requires the jQuery slider plugin.
Second, in your click event you're doing a location.reload, which is refreshing the page from the server, resetting any changes you had made to the page. (if you make the DIVs much smaller you can see one flash in before the page is reloaded).
You are getting a js error on the page -- "$.widget is not a function" because you didn't include the jqueryUI library. http://jqueryui.com/
Also if you remove the location.reload line, your code will work, however, I would rewrite that script block like this, so that everything clearly runs when the document is ready:
<script type="text/javascript">
$(document).ready(function() {
$("div.magnifyme").coverflow();
$("#add").click(function() {
$(".magnifyme").append("<div id=\"div5\">hello world</div>");
$("div.magnifyme").coverflow();
});
});
</script>