0

I am trying to find answers on how to toggle between two scroll positions and I believe that some of the answers that I am finding are a little too complicated for me on my own to figure out. Since I may not know how to google the right questions I'd thought I finally ask the community.

The end goal is to create a large accordion type page that opens up a projects details when the "Open Project" button is clicked.

My first challenge that i'd like to solve is to click the general "open project" button that will scroll me down to the top of the button. Then scroll me back up to the top of the parent div when clicked again. The button will eventually say "close project".

The ask:

  • click "open project" first time to scroll down to top of button
  • click "open project" again to scroll me to top of buttons parent div
  • have this() action on multiple buttons with the same class name

I have already looked at the thread jQuery click / toggle between two functions and the answers leave me a little lost when trying to apply scrollTo functionality. I have tried many attempts but then tried to solve it myself. Please be kind. I'm learning.

Any help would be great. Here is my prototype and jQuery:

$(".buttonToggleProjectDetails").click(function() {
  if ($(this) !== $(this).offset().top;) {
  $('html,body').animate({
    scrollTop: $(this).offset().top},
    'slow');
  } else {
    $('html,body').animate({
    scrollTop: $(this).parent().offset().top},'slow');
  }
});
anothermh
  • 9,815
  • 3
  • 33
  • 52

1 Answers1

0

Your condition (line 2 of your code) doesn't make any sense, because you are checking if a jQuery object is not equal to a number, which will be always true.

By reading "The ask" in your question, I assume that you want:

  1. to move to the top of the button on the odd clicks.
  2. to move to the top of the parent container on the even clicks.
  3. the above functionality for each button separately.

Code:

var
  /* Cache the buttons. */
  buttons = $(".buttonToggleProjectDetails"),

  /* Create an array of flags. */
  flags = Array(buttons.length);

/* Set the 'click' event. */
buttons.click(function() {
  var
    /* Define a variable to store the element whose offset will be used. */
    element,

    /* Cache the button. */
    button = $(this),

    /* Find the index of the button in the buttons collection. */
    index = [].indexOf.call(buttons, this);

  /* Reverse the flag. */
  flags[index] = !flags[index];

  /* Determine the element and the content of the button based on the click. */
  if (flags[index]) {
    element = button;
    button.html("Close Project");
  } else {
    element = button.parent();
    button.html("Open Project");
  }

  /* Animate the scroll. */
  $("html, body").animate({scrollTop: element.offset().top}, "slow");
});

You can find an updated version of your jsfiddle here or alternatively check the following snippet.

Snippet:

/* ----- JavaScript ----- */
var
  /* Cache the buttons. */
  buttons = $(".buttonToggleProjectDetails"),
  
  /* Create an array of flags. */
  flags = Array(buttons.length);

/* Set the 'click' event. */
buttons.click(function() {
  var
    /* Define a variable to store the element whose offset will be used. */
    element,
    
    /* Cache the button. */
    button = $(this),
    
    /* Find the index of the button in the buttons collection. */
    index = [].indexOf.call(buttons, this);
  
  /* Reverse the flag. */
  flags[index] = !flags[index];
  
  /* Determine the element and the content of the button based on the click. */
  if (flags[index]) {
    element = button;
    button.html("Close Project");
  } else {
    element = button.parent();
    button.html("Open Project");
  }

  /* Animate the scroll. */
  $("html, body").animate({scrollTop: element.offset().top}, "slow");
});
/* ----- CSS ----- */

* {
  padding: 0px;
  margin: 0px;
}

.projectContainer {
  width: 100%;
  background-color: aqua;
}

.projectHeader {
  max-width: 960px;
  width: 100%;
  height: 100vh;
  background-color: #ff7900;
  margin: 0 auto;
  position: relative;
}

.buttonToggleProjectDetails {
  padding: 10px 0;
  background-color: black;
  color: white;
  width: 200px;
  margin: 0 auto;
  text-align: center;
  position: absolute;
  bottom: 50px;
  left: 0;
  right: 0;
}

.projectDetails {
  max-width: 960px;
  width: 100%;
  height: 3000px;
  background-color: #FC5E61;
  margin: 0 auto;
  position: relative;
}

.one {
  background-color: blueviolet;
}

.two {
  background-color: antiquewhite;
}

.three {
  background-color: aliceblue;
}

.four {
  background-color: coral;
}

.five {
  background-color: darkcyan;
}
<!----- HTML ----->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="projectContainer">
  <div class="projectHeader one">
    <div class="buttonToggleProjectDetails">Open Project</div>
  </div>

  <div class="projectHeader two">
    <div class="buttonToggleProjectDetails">Open Project</div>
  </div>

  <div class="projectHeader three">
    <div class="buttonToggleProjectDetails">Open Project</div>
  </div>

  <div class="projectHeader four">
    <div class="buttonToggleProjectDetails">Open Project</div>
  </div>

  <div class="projectHeader five">
    <div class="buttonToggleProjectDetails">Open Project</div>
  </div>
</div>

Edit:

To check whether this is at the top of the viewport, you can use:

if ($(this).offset().top == $("html").scrollTop()) 
Angel Politis
  • 10,955
  • 14
  • 48
  • 66
  • Wow. Thanks @Angel. I have a lot of googling/learning to do. I thought it would be a lot more simple. For clarification on line 2 I was trying to say "If this() is not positioned at top of viewport...". I thought I was starting to get it but I guess not. Thanks for breaking it down for me too so I can digest it. – Justin Graham Jan 01 '18 at 21:03
  • You're welcome @JustinGraham. I'm glad I could help . Check out my edit regarding how you can write correctly the `if` statement on line 2. – Angel Politis Jan 01 '18 at 22:26