I am doing an assignment and I am trying to puzzle out why my jquery code is only working when I have console opened. The odd part about this behavior is that it works fine in Edge/IE but not chrome or firefox. I have searched through various threads and I doubled checked that my doc ready function was correctly formated and bracketed. EDIT: Added HTML and CSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Project 5: P3</title>
<meta name="author" content="Mia Kollia"><meta name="robots" content="noindex, nofollow">
<!-- STANDARD @IMPORT Google Font Gamja Flower -->
<link href="https://fonts.googleapis.com/css?family=Gamja+Flower" rel="stylesheet">
</head>
<body>
<aside class="logo">
<img src = "sftwear.png" alt="logo"><br>
</aside>
<aside class="Home">
<a href="../home.html">Home</a><br> <!-- Home link -->
</aside>
<article class="content">
<section class="intro">
<h1> Behold My Cats </h1>
</section>
<section class="pic">
<img class="image" src="pic2.jpg" height="200px" width="200px">
<img class="image" src="pic3.jpg" height="200px" width="200px">
<img class="image" src="pic4.jpg" height="200px" width="200px">
<img class="image" src="pic5.jpg" height="200px" width="200px">
</section>
<div id="savedspot"></div> <!-- used div here instead of p as I do not expect the viewer to see this -->
<p id="alertsection"></p>
<p id="alertsection2"></p> <!-- hidden until used by something -->
</article>
<style type="text/css">
body {
width:50em; /* Limits the space used by the document */
margin: auto;
text-align: center; /*aligns all text */
font-family: 'Gamja Flower', cursive;
}
article, aside >img{
background: linear-gradient(to bottom, #eab92d 0%,#c79810 100%);
border-radius: 1em;
}
.pic > img:nth-of-type(1){
position: relative;
display: block;
border-radius: 1em;
font-size: .8em;
padding: .5em;
margin: .5em;
color:black;
background: linear-gradient(to bottom, #4eacdb 0%,#1f96d1 50%,#007ebc 51%,#0084c5 100%) /* Tried to make a fancy gradient did not realllllly work */
}
.pic > img:nth-of-type(2){
position: relative;
display: block;
border-radius: 1em;
font-size: .8em;
padding: .5em;
margin: .5em;
color:black;
background: linear-gradient(to bottom, #4eacdb 0%,#1f96d1 50%,#007ebc 51%,#0084c5 100%) /* Tried to make a fancy gradient did not realllllly work */
}
.pic > img:nth-of-type(3){
position: relative;
display: block;
border-radius: 1em;
font-size: .8em;
padding: .5em;
margin: .5em;
color:black;
background: linear-gradient(to bottom, #4eacdb 0%,#1f96d1 50%,#007ebc 51%,#0084c5 100%) /* Tried to make a fancy gradient did not realllllly work */
}
.pic > img:nth-of-type(4){
position: relative;
display: block;
border-radius: 1em;
font-size: .8em;
padding: .5em;
margin: .5em;
color:black;
background: linear-gradient(to bottom, #4eacdb 0%,#1f96d1 50%,#007ebc 51%,#0084c5 100%) /* Tried to make a fancy gradient did not realllllly work */
}
</style>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
"use strict";
$(document).ready(function() {
console.log("I'm ready!")
$(".pic > img:nth-of-type(1)").click(function(){
var imgPosition1 = $(this).position();
if (imgPosition1.left>=300) {
$(this).stop().animate({left: 1}, 3000);
}
else{
$(this).stop().animate({left: 300}, 3000);
}
console.log(imgPosition1)
});
$(".pic > img:nth-of-type(2)").click(function(){
var imgPosition2 = $(this).position();
if (imgPosition2.left>=300) {
$(this).stop().animate({left: 1}, 3000);
}
else {
$(this).stop().animate({left: 300}, 3000);
}
console.log(imgPosition2)
});
$(".pic > img:nth-of-type(3)").click(function(){
var imgPosition3 = $(this).position();
if (imgPosition3.left>=300) {
$(this).stop().animate({left: 1}, 3000);
}
else {
$(this).stop().animate({left: 300}, 3000);
}
console.log(imgPosition3)
});
$(".pic > img:nth-of-type(4)").click(function(){
var imgPosition4 = $(this).position();
if (imgPosition4.left>=300) {
$(this).stop().animate({left: 1}, 3000);
}
else {
$(this).stop().animate({left: 300}, 3000);
}
console.log(imgPosition4)
});
});
</script>
</body>
<!-- gallery code above -->
It looks like your condition
if ($(this).position().left>=300) {...}
returns true
when console
is open. The animation does happen, but it's from left:0
to left: 1px
, over 3 seconds. Impossible to notice.
An improved version of it would be:
"use strict";
let t0 = performance.now();
$(document).ready(console.log("Ready in " + (performance.now() - t0) + 'ms.'))
$(window).on('load', () => {
console.log("Loaded in " + (performance.now() - t0) + 'ms.');
$('.pic').on('click tap', 'img', e => {
$(e.target).toggleClass('transformed')
})
});
@import('//fonts.googleapis.com/css?family=Gamja+Flower');
body {
margin: 0;
text-align: center;
font-family: 'Gamja Flower', cursive;
}
article,
aside>img {
background: linear-gradient(to bottom, #eab92d 0%, #c79810 100%);
border-radius: 1em;
}
.pic>img {
position: relative;
display: block;
border-radius: 1em;
font-size: .8em;
padding: .5em;
margin: .5em;
color: black;
background: linear-gradient(to bottom, #4eacdb 0%, #1f96d1 50%, #007ebc 51%, #0084c5 100%);
transition: transform 3s cubic-bezier(.4,0,.2,1);
transform: translateX(0);
}
.pic>img.transformed {
transform: translateX(300px);
}
<script src="//code.jquery.com/jquery-latest.min.js"></script>
<aside class="logo">
<img src="//picsum.photos/100/100" alt="logo"><br>
</aside>
<aside class="Home">
<a href>Home</a><br>
</aside>
<article class="content">
<section class="intro">
<h1> Behold My Cats </h1>
</section>
<section class="pic">
<img class="image" src="//picsum.photos/200/200" height="200px" width="200px">
<img class="image" src="//picsum.photos/200/200" height="200px" width="200px">
<img class="image" src="//picsum.photos/200/200" height="200px" width="200px">
<img class="image" src="//picsum.photos/200/200" height="200px" width="200px">
</section>
</article>
And here's a list of advantages:
.pic
, because the event is bound on the parent and only evaluates if the child is an <img>
when the event happens. If you had 1k images, you'd still bind only once and it would be as light, while using your method you'd need 1k bindings..animate()
, which is notoriously slow and resource expensive, it uses CSS animation. left
(which triggers repaint on subsequent elements), it animates transform
, which only triggers updates on the rendering layer - the element doesn't move in DOM. Only its' projection on the rendering layer is updated, without affecting anything else.Note: whenever you want to calculate/position images in a page, it's preferred to bind your code on window.onload
event (when all sync resources finished loading) rather than on DOM.ready
(when the DOM elements map was finished - when parser reached </html>
tag). ready
fires before onload
and typically images (especially if large) have not been loaded and the browser does not know their real size - therefore causing wrong calculations.
Another note: you should always try to perform your animations using CSS, as they're the least expensive (resource wise). Most times you will be able to perform everything you need animating transform
or opacity
and that's what you should aim for, as they are among the cheapest properties to animate. But CSS animations do have one downside: they don't have a complete
/done
callback. A way to perform an action or trigger an event when they've completed. When in need to chain animations, you need this callback and that's when you should turn to JavaScript animation libraries. When you do, my advice is to choose .velocity()
over jQuery's .animate()
. It's well worth the overhead.
$(window).on('load', () => {
$(".pic").on('click tap', '.image', function() {
$(this).velocity({
transform: $(this).position().left > 299.9 ?
"translateX(1px)":
"translateX(300px)"
}, {
duration: 1500,
easing: [ .42, 0, .2, 1 ]
});
});
});
@import('https://fonts.googleapis.com/css?family=Gamja+Flower');
body {
width: 100%;
margin: 0;
text-align: center;
font-family: 'Gamja Flower', cursive;
}
article,
aside>img {
background: linear-gradient(to bottom, #eab92d 0%, #c79810 100%);
border-radius: 1em;
}
.image {
position: relative;
display: block;
border-radius: 1em;
font-size: .8em;
padding: .5em;
margin: .5em;
color: black;
background: linear-gradient(to bottom, #4eacdb 0%, #1f96d1 50%, #007ebc 51%, #0084c5 100%)
}
<script src="//code.jquery.com/jquery-latest.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/velocity/2.0.2/velocity.min.js"></script>
<aside class="logo">
<img src="//picsum.photos/80/80" alt="logo"><br>
</aside>
<aside class="Home">
<a href>Home</a><br>
<!-- Home link -->
</aside>
<article class="content">
<section class="intro">
<h1> Behold My Cats </h1>
</section>
<section class="pic">
<img class="image" src="//picsum.photos/200/200" height="200px" width="200px">
<img class="image" src="//picsum.photos/200/200" height="200px" width="200px">
<img class="image" src="//picsum.photos/200/200" height="200px" width="200px">
<img class="image" src="//picsum.photos/200/200" height="200px" width="200px">
</section>
</article>
I should make a note here on the future of web animations, which takes best of both worlds (JS & CSS): Web Animations API. As light as CSS, without losing JS versatility. However, it still lacks support in IE and Safari, but on both the status is "Under consideration". So it'll be usable in production environments without polyfills in ~2-3 years.
Final note: you don't need the performance.now()
or the log()
s in the script, they're only there to show you when document.ready
and window.load
happen and how much they take from when script is parsed. Here's the short, clean version of that script:
$(window).on('load', () => {
$('.pic').on('click tap', 'img', e => $(e.target).toggleClass('transformed'))
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With