Animating two divs at same time onload, jquery help - javascript

I am trying to make a sort of "scales" look, where two divs will slowly animate up and down like being weighed on a scale. I could use some help with the functions though please, I can not get two to animate simultaneously on page load, and I need them to go up, then back down, then up, etc... Make sense? Here is what I have so far, I am kinda new to jquery obviously, :)
Thanks for any help!
<style type='text/css'>
body {
background: #262626;
}
.main
{
margin: 20px auto;
position:relative;
height:400px;
width:300px;
}
.content
{
float: left;
position:absolute;
bottom: 10px;
left: 100px;
height:40px;
width: 100px;
}
.content2
{
float: left;
position:absolute;
top: 10px;
left: 100px;
height:40px;
width: 100px;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".content").animate({top:'10px'},{ queue:true, duration:3000 }),
$(".content2").animate({bottom:'10px'},{ queue:true, duration:3000 });
});
</script>
<div class="main">
<div class="content">
<img src="pixel.png" alt="" />
</div>
<div class="content2">
<img src="functional.png" alt="" />
</div>
</div>

If you want them animated simultaneously, you should set queue to false.

document.ready does not wait for images to download. So use window.onload instead. And you should not be queueing if you want them to animate simultaneously. Also, I think in your animation you need to reset the top/bottom values respectively, so they don't interfere with each other...
$(window).load(function() {
$(".content").animate({top:'10px', bottom:0}, 3000);
$(".content2").animate({bottom:'10px', top:0}, 3000);
});

I think there should be a semicolon instead of a comma at the end of this line:
$(".content").animate({top:'10px'},{ queue:true, duration:3000 }),
That would explain why the next line is not being called.

For anyone looking for a solution. The queue: true statement kind of worked, but not really so I created another one.
If you're running the same animation, the best way to execute the command is to put them within one statement.
Use a comma to separate classes/ids.
ie) .content, .content2.
$(document).ready(function() {
$(".content, .content2").animate({top:'10px'},{ duration:3000 }),
done :)

Here is what I came up with, with help from various sources. This give the "teeter totter" effect on page load which I was going for.
<script>$(document).ready(function(){
$("#box1").animate({top:'+=150px'},3000 );
$("#box2").animate({top:'-=150px'},3000 );
$("#box1").animate({top:'-=150px'},3000 );
$("#box2").animate({top:'+=150px'},3000 );
$("#box1").animate({top:'+=100px'},4000 );
$("#box2").animate({top:'-=100px'},4000 );
$("#box1").animate({top:'-=100px'},4000 );
$("#box2").animate({top:'+=100px'},4000 );
$("#box1").animate({top:'+=50px'},5000 );
$("#box2").animate({top:'-=50px'},5000 );
$("#box1").animate({top:'-=20px'},5000 );
$("#box2").animate({top:'+=20px'},5000 );
});
</script>
I'm afraid this may be too "brute force", but I don't know of a better, smoother way to do this.

Related

how to Make the call back to run only once scroll Trigger GSAP?

I am using the GSAP animation library for adding scroll animation to the website, and for that, I have a custom Callback onEnter:() (at the bottom of the page on the green box "C" {for that please check the code}) it runs the function and shows the message in the console once it enters the viewport but if I again go up and scroll down this functions runs again I want this function to run only once in spite the user is scrolling up and down many times it has to run a single time.
I tried to find the answer to this question all over the internet even on the GSAP forums but didn't get any idea So can anyone please tell me how I can do that?
gsap.registerPlugin(ScrollTrigger);
gsap.to(".c",{
scrollTrigger:{
trigger:".c",
onEnter:test,
start:"top center",
markers:true,
},
x:400,
rotation:300,
immediateRender: true,
duration:3
})
function test(){
console.log("I am entered")
}
.sc-div{
height:100px;
width:100px;
display: flex;
align-items:center;
justify-content:center;
}
.a{
background:red;
margin-top:50px;
}
.b{
background: yellow;
}
.c{
background: green;
margin-bottom: 400px;
}
.mt{
margin-top:500px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/ScrollTrigger.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<div class="a sc-div">A</div>
<div class="b sc-div mt">B</div>
<div class="c sc-div mt">C</div>
I got it! how to do this I just have to add the once: true property in the Scroll trigger Object and it will gonna run only once even after I Scroll multiple times in the viewport

Why is my jQuery toggle not working?

I'm trying to set up a side menu and having some trouble with the jQuery Toggle. Everything else seems to function fine. I did try for a about 2 hours before posting here, so been getting a little frustrated (seeing how this is pretty basic stuff). Any suggestions?
Below is the format and exact order of my page layout, I only added separator text ("The side menu", "Image I click..", etc.) to make reading/understanding easier. Any help would be greatly appreciated.
The side menu:
<div id="SideMenu" class="sidenav">
<img class="CloseBtn" src="./wht_menu.png" />
Link 1
Link 2
Link 3
Link 4
Link 5
</div>
Image I click to open the menu:
<img class="OpenBtn" src="./blk_menu.png" />
The rest of my page:
<div id="main">
My main page content goes here...
</div>
My CSS & jQuery:
<!--Slider Menu-->
<script>
$(".OpenBtn").click(function() {
$("#SideMenu").fadeToggle("fast", "swing");
});
</script>
<style>
#SideMenu{
width: 250px;
display: none;
}
</style>
You need to wrap the jQuery in this block (docs):
$( document ).ready(function() {
$(".OpenBtn").click(function() {
$("#SideMenu").fadeToggle("fast", "swing");
});
});
Working example using your code:
http://codepen.io/anon/pen/xEaqqA
There is a possibility that jQuery not loaded on page at the time.
<script>
(function($){
$(document).ready(function(){
$(".OpenBtn, .CloseBtn").click(function() {
$("#SideMenu").fadeToggle("fast", "swing");
});
});
})(jQuery);
</script>
Thanks for your help everyone! Although pivemi's answer was not the solution, a deeper review of his codepen link got things working, my doc wasn't calling on the jQuery library. Adding this to the top was my solution:
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
Your CSS could look like this:
.menu {
position: fixed;
height: 100%;
width: 272px;
padding-bottom: 50px;
overflow: auto;
box-shadow: 0 0 10px 0 rgba(0,0,0,.75);
background-color: #fff;
z-index: 999;
display: none;}
And your jQuery script:
$(document).ready(function(){
$('.show-menu').click(function(){
fade_menu();
});
$('.menu-item').click(function(){
fade_menu();
});});});
function fade_menu(){
$('.menu').fadeToggle("fast");
}

Determine HTML element position change

EDIT: See update!
I have the following html:
<body>
<span id="milestone1">
</span>
<img id="image1" src="blabla.jpeg" style="width:400px;height:200px;" />
<div id="divOverlayOverImage1" style="position:absolute; top:100px; left:40px; width:400px;height:200px;" onclick="DoFunkyStuff();"><div>
</body>
At first the divOverlayOverImage1 is positioned over Image1, covering it, but if I run the code below, the #divOverlayOverImage1 element will no longer covering the #image1 element.
$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
I want to have an event that notifies me when #image1 changes its position, so I can update the position of #divOverlayOverImage1.
NOTE: I do not have full control over the dom. the $("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">'); command is run by a third party.
UPDATE: I do not have full control of the DOM, so I cannt put a callback to the element add function, as it is not me making this call.
Also, I cannot modify HTML like crazy. I just come to a set of websites, append and overlay to a specific image throung JavaScript and that's it. There are other competitiors that change the HTML as well.
If you have full control over the DOM, and I assume you have, you can add a call to every change you make in the DOM that will affect that <span>.
function yourFunction() {
$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
updateMyOverlayPosition();
}
if that doesnt work, you might try this one here: Detect changes in the DOM
edit
if you want events:
$('#image').on('adjustOverlay',function(e) {
// adjust the position of the overlay
}
$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
$('#image').trigger('adjustOverlay', {extra: "info", some: "parameters"});
edit2
Since you don't have full control over changes in the DOM and you can get surprised you can either go with the link I already provided above or check in an interval if the overlay is still where it needs to be. This doesn't solve the problem in the way you want it, but there is no native event on DOM-changes, so you have to stick with some sort of work-around.
var checkTime = 100; //100 ms interval
var check = setInterval(function() {
// adjust overlay position
}, checkTime);
edit3
next possible solution: if you know how affecting code is inserted in the DOM, you can try to change that method so that it always runs your adjustOverlayPosition() or fires an event, if you like events. Example: if it is inserted with jQuery's .after() you can modify that function:
jQuery.fn.extend({
// since the .after() function already exists, this will
// actually overwrite the original function. Therefore you need
// the exact code that was originally used to recreate it.
after: function() {
return this.domManip( arguments, function( elem ) {
if ( this.parentNode ) {
this.parentNode.insertBefore( elem, this.nextSibling );
}
// call the function directly
adjustOverlayPosition();
// or call an event
$('#image').trigger('adjustOverlay', {extra: "info", some: "parameters"});
}
});
Drawback: this solution can be risky and works only if you know the code that is used originally. So it would also depend on the jQuery version.
One workaround is to reorganize your layout.
Wrap your image and overlay into a div. That way they will always remain that way.
<div id="wrap">
<img id="i1" src="..." />
<div id="overlay" />
</div>
#wrap {
position: relative;
width: 400px;
height: 200px;
}
#overlay {
position: absolute;
top: 100px;
left: 40px;
width: 400px;
height: 200px;
}
If wrapping the img with a ovelay is only your requirement, I think you can go with a pure css Solution:
Try the demo
HTML
<p id="milestone1">
First Overlay
</p>
<div class="img-overlay-container" style="width:400px;height:200px;">
<img id="image1" src="blabla.jpeg"/>
<div id="overlay1" onclick="alert('clicked');">
</div>
</div>
<p id="milestone2">
Second Overlay
</p>
<div class="img-overlay-container" style="width:100px;height:400px;">
<img id="image2" src="blabla.jpeg"/>
<div id="overlay2" onclick="alert('clicked');">
</div>
</div>
CSS
.img-overlay-container{
position: relative;
display:inline-block;
}
.img-overlay-container > img{
}
.img-overlay-container > div{
position:absolute;
top:0px;
left:0px;
width:100%;
height:100%;
background: rgba(3,3,3,.1);
}
function changePosition(callback) {
$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
callback();
}
Then you can call changePosition(function() {// Add your event handler function}).
Hope this will help you!

duplicate div then do a horizontal scroll

I'm trying to clone #main then put my ajax result there (hidden), after doing so I will make it scroll horizontally to the left hiding the current one then display the clone.
HTML:
<div class="container">
<div id="main">
<p>Click here to start</p>
</div>
</div>​
CSS:
#main{
width:460px;
min-height:200px;
background:#3F9FD9;
margin:0 auto;
}
.container {
position:relative;
}
​
Javascript:
$('#main').click(function(){
//clone.html(data)
var clone = $(this).clone().html('<p>Ajax loaded content</p>').css(
{position:'absolute',right:'0','margin-right':'-460px',top:0}
).attr('class','love').insertAfter($(this));
$(this).css({position:'relative'});
var width = $(window).width()-$(this).outerWidth()/2;
$('#main').animate({'left':'-'+width},4000);
});
but i'm stuck on the idea on how to make both #main animate to the left and position the second div at the center?
Fiddle
EDIT: Now i'm only stuck on how to animate the clone.
I sort of took a different approach to your question, is this kind of what you are looking for?
http://jsfiddle.net/3s7Fw/5/show
I thought, rather than do some animating ourselves, why not let jQuery's hide function do it for us? This could definitely be made to work better, but it communicates the thought.
JavaScript
$('.container').on('click', '.loaded-content', function(){
$this = $(this);
//clone.html(data)
var clone = $this.clone().html('<p>Ajax loaded content</p>').attr("id", '');
$this.after(clone);
$this.hide('slow');
});​
HTML
<div class="container">
<div id="main" class="loaded-content">
<p>Click here to start</p>
</div>
</div>​
CSS
#main, .loaded-content{
width:460px;
min-height:200px;
background:#3F9FD9;
margin:0 auto;
float: left;
}
.container {
position:relative;
width: 920px;
}
​If this is not the desired functionality, then you might be interested in a slider. There are a number of good slider plugins already out there that you can use. The difficult part would probably be adding a addNewSlide function to your chosen slider, assuming it didn't already have one.

jQuery UI (RAD/GUI) form designer

Well, I'm working on a visual form designer and decided to use jQuery UI as both the end form widgetset as well as the widgetset for the designer itself.
My main concern is to make jQuery wigets "read-only". I've had the following idea:
<style type="text/css">
.widget-wrap { position: relative; }
.widget-overlay { position: absolute; left:0; right:0; top:0; bottom:0; /*maybe z-index as well*/ }
</style>
<div class="widget-wrap" id="wdt1">
<button class="jquery-widget">Hello World!</button>
<div class="widget-overlay"><!----></div>
</div>
<script type="text/javascript">
$(function() {
$("button.jquery-widget").button();
});
function widgetLock(){
$("#wdt1 .widget-overlay").show();
}
function widgetRelease(){
$("#wdt1 .widget-overlay").hide();
}
</script>
Hope my example makes sense :)
My questions are;
does this sound good to you?
do you know of a better or another way?
do you see any possible issues with it?
I would say this is a very bad idea in that 1) you may find the overlay in a weird place in certain browser resolutions etc and 2) you can still tab to the item.
Much better to either;
Hide the element
Disable the element
Replace text boxes with labels, buttons with graphics etc.
Disable the click on the button
edit
You can use jQuery to unbind events on elements and then you can re-bind them later on.
If I was to build a form designer I'd make all elements divs with an image of the actual widget as a css background image, that way you can drag the widget representation around the form without activating it or having any of the overlay problems.
If you really wanted to make it look like the finished product you can have the actual widget nested inside the div but invisible when the users mouse is within the div, when the user moves the mouse out of the div then set the widget visible again.
DC
Yes I was aware that the background image would look wrong when stretched. So I thought about it on the way home. A better technique would be to create a widget sandwich
place the widget between 2 divs the bottom div controls the size and position the top prevents the widget from activating
<html>
<head>
<script language="JavaScript" type="text/JavaScript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script language="JavaScript" type="text/JavaScript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.js"></script>
<style type="text/css">
<!--
.widget {
height: 100%;
width: 100%;
}
.widget_overlay {
border: thin solid #FF0000;
position: absolute;
top: 1px;
left: 1px;
right: 1px;
bottom: 1px;
right: 1px;
visibility:visible
}
.sz_controller {
position:absolute;
width:365px;
height:61px;
left: 142px;
top: 75px;
}
-->
</style>
<script language="JavaScript" type="text/JavaScript">
function ShowHide(button,id){
elem = document.getElementById(id)
if (elem.style.visibility=='hidden') {
elem.style.visibility='visible';
button.value="Hide Overlay";
} else {
elem.style.visibility = 'hidden';
button.value="Show Overlay";
}
}
</script>
</head>
<body>
<input type="button" name="Button" value="Hide Overlay" onClick="ShowHide(this,'widget_overlay')">
<div id="draggable" class="sz_controller" style=""><select class="widget" name="test">
<option>test 1</option>
<option>test 2</option>
<option>test 3</option>
</select><div id="widget_overlay" class="widget_overlay"></div></div>
<script>
$(function() {
$( "#draggable" ).draggable();
});
</script>
</body>
</html>
The above will work in firefox
Clicking the button hides the overlay div allowing testing of the widget, You can drag the object around the screen, no resizing logic has been implemented.
DC

Categories