0

I'm trying to use when and done to make the second function run only after the first one is executed, but it's not working. What I'm trying to achieve here is:

First I use $("#jobshome").load("jobs/newest-jobs .js-toprow"); to load a div from an external page (In the same domain, no cross domain here), then after it is fully loaded, the next script, which is a simple text slider, will run. But now the external HTML isn't loading inside the "#jobshome" anymore.

The result that I get when I don't use this approach is that the whole external div will load inside a single slider, and that's not what I need.

If I use the initial part like this it works, but not as expected:

$(function(){$("#jobshome").load("jobs/newest-jobs .js-toprow");});
        $(function(){

    //rotation speed and timer

My code is as follows:

jQuery(document).ready(function($) {

  $.when(function() {
    $("#jobshome").load("jobs/newest-jobs .js-toprow");
  }).done(function() {

    //rotation speed and timer
    var speed = 3000;
    var run = setInterval(rotate, speed);
    var slides = $('.js-toprow');
    var container = $('#jobshome');
    var elm = container.find(':first-child').prop("tagName");
    var item_height = container.height();
    var previous = 'prevabc'; //id of previous button
    var next = 'nextabc'; //id of next button
    slides.height(item_height); //set the slides to the correct pixel height
    container.parent().height(item_height);
    container.height(slides.length * item_height); //set the slides container to the correct total height
    container.find(elm + ':first').before(container.find(elm + ':last'));
    resetSlides();


    //if user clicked on prev button

    $('#buttonsabc a').click(function(e) {
      //slide the item

      if (container.is(':animated')) {
        return false;
      }
      if (e.target.id == previous) {
        container.stop().animate({
          'top': 0
        }, 1500, function() {
          container.find(elm + ':first').before(container.find(elm + ':last'));
          resetSlides();
        });
      }

      if (e.target.id == next) {
        container.stop().animate({
          'top': item_height * -2
        }, 1500, function() {
          container.find(elm + ':last').after(container.find(elm + ':first'));
          resetSlides();
        });
      }
      //cancel the link behavior            
      return false;

    });

    //if mouse hover, pause the auto rotation, otherwise rotate it    
    container.parent().mouseenter(function() {
      clearInterval(run);
    }).mouseleave(function() {
      run = setInterval(rotate, speed);
    });


    function resetSlides() {
      //and adjust the container so current is in the frame
      container.css({
        'top': -1 * item_height
      });
    }

  });
});
//a simple function to click next link
//a timer will call this function, and the rotation will begin

function rotate() {
  jQuery('#nextabc').click();
}
#carouselabc {
  position: relative;
  width: 60%;
  margin: 0 auto;
}

#slidesabc {
  overflow: hidden;
  position: relative;
  width: 100%;
  height: 250px;
}

#areadoslideabc {
  list-style: none;
  width: 100%;
  height: 250px;
  margin: 0;
  padding: 0;
  position: relative;
}

#slidesabcdef {
  width: 100%;
  height: 250px;
  float: left;
  text-align: center;
  position: relative;
  font-family: lato, sans-serif;
}


/* Styling for prev and next buttons */

.btn-barabc {
  max-width: 346px;
  margin: 0 auto;
  display: block;
  position: relative;
  top: 40px;
  width: 100%;
}

#buttonsabc {
  padding: 0 0 5px 0;
  float: right;
}

#buttonsabc a {
  text-align: center;
  display: block;
  font-size: 50px;
  float: left;
  outline: 0;
  margin: 0 60px;
  color: #b14943;
  text-decoration: none;
  display: block;
  padding: 9px;
  width: 35px;
}

a#prevabc:hover,
a#next:hover {
  color: #FFF;
  text-shadow: .5px 0px #b14943;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="carouselabc">
  <div class="btn-barabc">
    <div id="buttonsabc">
      <a id="prevabc" href="#">Previous</a>
      <a id="nextabc" href="#">Next</a>
    </div>
  </div>
  <div id="slidesabc">
    <div id="jobshome"></div>
  </div>
</div>

Script source: https://codepen.io/TyStelmach/pen/yygvNK

Matt
  • 15
  • 9
  • 1
    Have you thought of using a global flag. You could use an if statement to see if the state exists as true or false. I use it all the time and it works for me. – Cam Sep 11 '18 at 22:53
  • I used `console.log("text");` inside each function to see if everything is working. Only the second function is. – Matt Sep 11 '18 at 22:55
  • Have you tried using .then instead of .done. https://makandracards.com/makandra/39543-jquery-promises-done-and-then-are-not-the-same – Cam Sep 11 '18 at 22:59
  • Yes, I did. It still doesn't work. – Matt Sep 11 '18 at 23:27

1 Answers1

1

Why dont you use the callback of load() function?

$("#jobshome").load("jobs/newest-jobs .js-toprow", () => {
   //do stuff after loading the html
}); 

when doesn't work because it expects a Promise or Deferred object and if its neither it treats the value passed as a resolved Deferred (which basically means it doesn't wait, but executes then/done right away).

vicbyte
  • 3,690
  • 1
  • 11
  • 20
  • What's the meaning of `=>`? – Matt Sep 11 '18 at 23:46
  • Arrow function, you might as well replace `() => ` with `function()`, more on those: https://stackoverflow.com/questions/24900875/whats-the-meaning-of-an-arrow-formed-from-equals-greater-than-in-javas – vicbyte Sep 11 '18 at 23:47
  • I used your solution and it worked. But then I don't get a slideshow loop anymore. – Matt Sep 11 '18 at 23:52
  • Not sure what you mean by "slideshow loop", but have you placed all the code that needs to run after the content is loaded into the callback function? – vicbyte Sep 11 '18 at 23:55
  • `Uncaught DOMException: Failed to execute 'insertBefore' on 'Node': The new child element contains the parent.` – Matt Sep 11 '18 at 23:55
  • The slideshow was retrieved from here. It does execute a looping, but after I tried your solution, it looks like it's still running forever, but there's an element nesting problem. – Matt Sep 11 '18 at 23:58
  • Placed everything inside the callback now. Same. – Matt Sep 12 '18 at 00:00
  • Could you comment out all the lines that contain this: `container.find(elm + ':last').after(container.find(elm + ':first'));` And check if the slideshow appears? – vicbyte Sep 12 '18 at 00:01
  • Did that. Now it's not sliding to the next element. The problem that I'm having is that it slides well until a certain item, then the layout breaks like there's a float right (CSS) and then it disappear. Can you test the code locally? – Matt Sep 12 '18 at 00:38
  • Ok, thank you very much sir, I'll make sure to follow the advice. – Matt Sep 12 '18 at 01:07