Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery only working within console even w/ document ready

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 -->
like image 302
Mia Avatar asked May 08 '18 14:05

Mia


1 Answers

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:

  • it's DRY - there's no need to repeat the same code for each image. You can code it once for all.
  • It only binds once, on the parent, for all images, including future ones added later on to .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.
  • instead of using jQuery's .animate(), which is notoriously slow and resource expensive, it uses CSS animation.
  • instead of animating 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.
  • instead of calculating the current position to determine if you need to move it one way or the other, you simply control direction using existence of a class on the element, allowing you to turn the animation mid-transition, as many times as you want, with minimal cost and no position calculation.

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'))
});
like image 88
tao Avatar answered Sep 24 '22 17:09

tao