Keep Scroll position when elements above toggle visible/invisible












1















searching for this did not find a proper answer, yet I am sure I am not the only one having this issue.



I do have a loooong page (up to more than 10000px height) with lots of 's. Some of them are set to display:hidden and zero height using this css class:



.invisible {
visibility:hidden;
height:0px;
margin:0 !important;
padding:0 !important;
border-width:0 !important;
min-height:0 !important;
}


So my html basically looks like this (I omitted the closing tags):



<div class="invisible">
<div class="invisible">
<div class="invisible">
<div class="invisible">
<div class="invisible">
<div class="invisible">
<div>
<div class="invisible">
<div>
<div>
<div>
<div>
<div class="invisible">
<div class="invisible">
<div class="invisible">
<div>
<div>
<div>
<div>


So if I am in the middle of the page and toggle all .invisible classes, the page gets a lot higher (because all the divs that were .invisible regain their real height), and the element(s) that were on screen before are not any more.



And that is exactly what I want to achieve: Keep the element that was on-screen before toggling on-screen after toggling, so the user does not really notice any scrolling.



I can think of a way doing this:
1) Somehow find out which element is on screen and how far it is from the screen top (thats where I fail at this idea)
2) when toggling, scoll until exactly this state is reached again



As my JS aint too good, there maybe a better way than my initial idea...



Best regards
Philipp










share|improve this question





























    1















    searching for this did not find a proper answer, yet I am sure I am not the only one having this issue.



    I do have a loooong page (up to more than 10000px height) with lots of 's. Some of them are set to display:hidden and zero height using this css class:



    .invisible {
    visibility:hidden;
    height:0px;
    margin:0 !important;
    padding:0 !important;
    border-width:0 !important;
    min-height:0 !important;
    }


    So my html basically looks like this (I omitted the closing tags):



    <div class="invisible">
    <div class="invisible">
    <div class="invisible">
    <div class="invisible">
    <div class="invisible">
    <div class="invisible">
    <div>
    <div class="invisible">
    <div>
    <div>
    <div>
    <div>
    <div class="invisible">
    <div class="invisible">
    <div class="invisible">
    <div>
    <div>
    <div>
    <div>


    So if I am in the middle of the page and toggle all .invisible classes, the page gets a lot higher (because all the divs that were .invisible regain their real height), and the element(s) that were on screen before are not any more.



    And that is exactly what I want to achieve: Keep the element that was on-screen before toggling on-screen after toggling, so the user does not really notice any scrolling.



    I can think of a way doing this:
    1) Somehow find out which element is on screen and how far it is from the screen top (thats where I fail at this idea)
    2) when toggling, scoll until exactly this state is reached again



    As my JS aint too good, there maybe a better way than my initial idea...



    Best regards
    Philipp










    share|improve this question



























      1












      1








      1








      searching for this did not find a proper answer, yet I am sure I am not the only one having this issue.



      I do have a loooong page (up to more than 10000px height) with lots of 's. Some of them are set to display:hidden and zero height using this css class:



      .invisible {
      visibility:hidden;
      height:0px;
      margin:0 !important;
      padding:0 !important;
      border-width:0 !important;
      min-height:0 !important;
      }


      So my html basically looks like this (I omitted the closing tags):



      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div>
      <div class="invisible">
      <div>
      <div>
      <div>
      <div>
      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div>
      <div>
      <div>
      <div>


      So if I am in the middle of the page and toggle all .invisible classes, the page gets a lot higher (because all the divs that were .invisible regain their real height), and the element(s) that were on screen before are not any more.



      And that is exactly what I want to achieve: Keep the element that was on-screen before toggling on-screen after toggling, so the user does not really notice any scrolling.



      I can think of a way doing this:
      1) Somehow find out which element is on screen and how far it is from the screen top (thats where I fail at this idea)
      2) when toggling, scoll until exactly this state is reached again



      As my JS aint too good, there maybe a better way than my initial idea...



      Best regards
      Philipp










      share|improve this question
















      searching for this did not find a proper answer, yet I am sure I am not the only one having this issue.



      I do have a loooong page (up to more than 10000px height) with lots of 's. Some of them are set to display:hidden and zero height using this css class:



      .invisible {
      visibility:hidden;
      height:0px;
      margin:0 !important;
      padding:0 !important;
      border-width:0 !important;
      min-height:0 !important;
      }


      So my html basically looks like this (I omitted the closing tags):



      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div>
      <div class="invisible">
      <div>
      <div>
      <div>
      <div>
      <div class="invisible">
      <div class="invisible">
      <div class="invisible">
      <div>
      <div>
      <div>
      <div>


      So if I am in the middle of the page and toggle all .invisible classes, the page gets a lot higher (because all the divs that were .invisible regain their real height), and the element(s) that were on screen before are not any more.



      And that is exactly what I want to achieve: Keep the element that was on-screen before toggling on-screen after toggling, so the user does not really notice any scrolling.



      I can think of a way doing this:
      1) Somehow find out which element is on screen and how far it is from the screen top (thats where I fail at this idea)
      2) when toggling, scoll until exactly this state is reached again



      As my JS aint too good, there maybe a better way than my initial idea...



      Best regards
      Philipp







      javascript css






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 21 '18 at 21:10









      isherwood

      37.2k1082111




      37.2k1082111










      asked Nov 21 '18 at 20:25









      PhilippGPhilippG

      133




      133
























          1 Answer
          1






          active

          oldest

          votes


















          0














          I was able to do it using document.elementFromPoint, below there's a working demo but it doesn't seem to be working 100% inside SO's sandbox so please also check https://jsbin.com/hozazusone/1 (it might need some fine-tuning):






          $('#toggle').on('click', function(){
          var top = $(document.elementFromPoint(window.innerWidth/2, 10))
          var howMuchFromTop = top.offset().top - window.scrollY
          $('.invisible').removeClass('invisible').addClass('red')
          window.scrollTo(0, top.offset().top - howMuchFromTop)
          })

          .invisible {
          visibility:hidden;
          height:0px;
          margin:0 !important;
          padding:0 !important;
          border-width:0 !important;
          min-height:0 !important;
          }

          div {
          background: #cccaaa;
          height: 110px;
          margin: 4px 0 0 0;
          }

          .red {
          background: red;
          }


          #toggle {
          position: fixed;
          top: 0;
          left: 0;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div>1</div>
          <div>2</div>
          <div class="invisible">3</div>
          <div class="invisible">4</div>
          <div>5</div>
          <div class="invisible">6</div>
          <div>7</div>
          <div class="invisible">8</div>
          <div>9</div>
          <div>10</div>
          <div>11</div>
          <div>12</div>
          <div class="invisible">13</div>
          <div class="invisible">14</div>
          <div class="invisible">15</div>
          <div>16</div>
          <div>17</div>
          <div>18</div>
          <div>19</div>
          <div>20</div>
          <div>21</div>
          <div>22</div>


          <button id="toggle">toggle</button>








          share|improve this answer





















          • 1





            Wow, this is super-awesome, thanks a lot! elementFromPoint() was what I was missing, goot to know that one.

            – PhilippG
            Nov 21 '18 at 21:10











          • Glad it works for you. As for browser support it seems to be fine caniuse.com/#feat=element-from-point

            – enapupe
            Nov 21 '18 at 21:12













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419970%2fkeep-scroll-position-when-elements-above-toggle-visible-invisible%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          I was able to do it using document.elementFromPoint, below there's a working demo but it doesn't seem to be working 100% inside SO's sandbox so please also check https://jsbin.com/hozazusone/1 (it might need some fine-tuning):






          $('#toggle').on('click', function(){
          var top = $(document.elementFromPoint(window.innerWidth/2, 10))
          var howMuchFromTop = top.offset().top - window.scrollY
          $('.invisible').removeClass('invisible').addClass('red')
          window.scrollTo(0, top.offset().top - howMuchFromTop)
          })

          .invisible {
          visibility:hidden;
          height:0px;
          margin:0 !important;
          padding:0 !important;
          border-width:0 !important;
          min-height:0 !important;
          }

          div {
          background: #cccaaa;
          height: 110px;
          margin: 4px 0 0 0;
          }

          .red {
          background: red;
          }


          #toggle {
          position: fixed;
          top: 0;
          left: 0;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div>1</div>
          <div>2</div>
          <div class="invisible">3</div>
          <div class="invisible">4</div>
          <div>5</div>
          <div class="invisible">6</div>
          <div>7</div>
          <div class="invisible">8</div>
          <div>9</div>
          <div>10</div>
          <div>11</div>
          <div>12</div>
          <div class="invisible">13</div>
          <div class="invisible">14</div>
          <div class="invisible">15</div>
          <div>16</div>
          <div>17</div>
          <div>18</div>
          <div>19</div>
          <div>20</div>
          <div>21</div>
          <div>22</div>


          <button id="toggle">toggle</button>








          share|improve this answer





















          • 1





            Wow, this is super-awesome, thanks a lot! elementFromPoint() was what I was missing, goot to know that one.

            – PhilippG
            Nov 21 '18 at 21:10











          • Glad it works for you. As for browser support it seems to be fine caniuse.com/#feat=element-from-point

            – enapupe
            Nov 21 '18 at 21:12


















          0














          I was able to do it using document.elementFromPoint, below there's a working demo but it doesn't seem to be working 100% inside SO's sandbox so please also check https://jsbin.com/hozazusone/1 (it might need some fine-tuning):






          $('#toggle').on('click', function(){
          var top = $(document.elementFromPoint(window.innerWidth/2, 10))
          var howMuchFromTop = top.offset().top - window.scrollY
          $('.invisible').removeClass('invisible').addClass('red')
          window.scrollTo(0, top.offset().top - howMuchFromTop)
          })

          .invisible {
          visibility:hidden;
          height:0px;
          margin:0 !important;
          padding:0 !important;
          border-width:0 !important;
          min-height:0 !important;
          }

          div {
          background: #cccaaa;
          height: 110px;
          margin: 4px 0 0 0;
          }

          .red {
          background: red;
          }


          #toggle {
          position: fixed;
          top: 0;
          left: 0;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div>1</div>
          <div>2</div>
          <div class="invisible">3</div>
          <div class="invisible">4</div>
          <div>5</div>
          <div class="invisible">6</div>
          <div>7</div>
          <div class="invisible">8</div>
          <div>9</div>
          <div>10</div>
          <div>11</div>
          <div>12</div>
          <div class="invisible">13</div>
          <div class="invisible">14</div>
          <div class="invisible">15</div>
          <div>16</div>
          <div>17</div>
          <div>18</div>
          <div>19</div>
          <div>20</div>
          <div>21</div>
          <div>22</div>


          <button id="toggle">toggle</button>








          share|improve this answer





















          • 1





            Wow, this is super-awesome, thanks a lot! elementFromPoint() was what I was missing, goot to know that one.

            – PhilippG
            Nov 21 '18 at 21:10











          • Glad it works for you. As for browser support it seems to be fine caniuse.com/#feat=element-from-point

            – enapupe
            Nov 21 '18 at 21:12
















          0












          0








          0







          I was able to do it using document.elementFromPoint, below there's a working demo but it doesn't seem to be working 100% inside SO's sandbox so please also check https://jsbin.com/hozazusone/1 (it might need some fine-tuning):






          $('#toggle').on('click', function(){
          var top = $(document.elementFromPoint(window.innerWidth/2, 10))
          var howMuchFromTop = top.offset().top - window.scrollY
          $('.invisible').removeClass('invisible').addClass('red')
          window.scrollTo(0, top.offset().top - howMuchFromTop)
          })

          .invisible {
          visibility:hidden;
          height:0px;
          margin:0 !important;
          padding:0 !important;
          border-width:0 !important;
          min-height:0 !important;
          }

          div {
          background: #cccaaa;
          height: 110px;
          margin: 4px 0 0 0;
          }

          .red {
          background: red;
          }


          #toggle {
          position: fixed;
          top: 0;
          left: 0;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div>1</div>
          <div>2</div>
          <div class="invisible">3</div>
          <div class="invisible">4</div>
          <div>5</div>
          <div class="invisible">6</div>
          <div>7</div>
          <div class="invisible">8</div>
          <div>9</div>
          <div>10</div>
          <div>11</div>
          <div>12</div>
          <div class="invisible">13</div>
          <div class="invisible">14</div>
          <div class="invisible">15</div>
          <div>16</div>
          <div>17</div>
          <div>18</div>
          <div>19</div>
          <div>20</div>
          <div>21</div>
          <div>22</div>


          <button id="toggle">toggle</button>








          share|improve this answer















          I was able to do it using document.elementFromPoint, below there's a working demo but it doesn't seem to be working 100% inside SO's sandbox so please also check https://jsbin.com/hozazusone/1 (it might need some fine-tuning):






          $('#toggle').on('click', function(){
          var top = $(document.elementFromPoint(window.innerWidth/2, 10))
          var howMuchFromTop = top.offset().top - window.scrollY
          $('.invisible').removeClass('invisible').addClass('red')
          window.scrollTo(0, top.offset().top - howMuchFromTop)
          })

          .invisible {
          visibility:hidden;
          height:0px;
          margin:0 !important;
          padding:0 !important;
          border-width:0 !important;
          min-height:0 !important;
          }

          div {
          background: #cccaaa;
          height: 110px;
          margin: 4px 0 0 0;
          }

          .red {
          background: red;
          }


          #toggle {
          position: fixed;
          top: 0;
          left: 0;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div>1</div>
          <div>2</div>
          <div class="invisible">3</div>
          <div class="invisible">4</div>
          <div>5</div>
          <div class="invisible">6</div>
          <div>7</div>
          <div class="invisible">8</div>
          <div>9</div>
          <div>10</div>
          <div>11</div>
          <div>12</div>
          <div class="invisible">13</div>
          <div class="invisible">14</div>
          <div class="invisible">15</div>
          <div>16</div>
          <div>17</div>
          <div>18</div>
          <div>19</div>
          <div>20</div>
          <div>21</div>
          <div>22</div>


          <button id="toggle">toggle</button>








          $('#toggle').on('click', function(){
          var top = $(document.elementFromPoint(window.innerWidth/2, 10))
          var howMuchFromTop = top.offset().top - window.scrollY
          $('.invisible').removeClass('invisible').addClass('red')
          window.scrollTo(0, top.offset().top - howMuchFromTop)
          })

          .invisible {
          visibility:hidden;
          height:0px;
          margin:0 !important;
          padding:0 !important;
          border-width:0 !important;
          min-height:0 !important;
          }

          div {
          background: #cccaaa;
          height: 110px;
          margin: 4px 0 0 0;
          }

          .red {
          background: red;
          }


          #toggle {
          position: fixed;
          top: 0;
          left: 0;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div>1</div>
          <div>2</div>
          <div class="invisible">3</div>
          <div class="invisible">4</div>
          <div>5</div>
          <div class="invisible">6</div>
          <div>7</div>
          <div class="invisible">8</div>
          <div>9</div>
          <div>10</div>
          <div>11</div>
          <div>12</div>
          <div class="invisible">13</div>
          <div class="invisible">14</div>
          <div class="invisible">15</div>
          <div>16</div>
          <div>17</div>
          <div>18</div>
          <div>19</div>
          <div>20</div>
          <div>21</div>
          <div>22</div>


          <button id="toggle">toggle</button>





          $('#toggle').on('click', function(){
          var top = $(document.elementFromPoint(window.innerWidth/2, 10))
          var howMuchFromTop = top.offset().top - window.scrollY
          $('.invisible').removeClass('invisible').addClass('red')
          window.scrollTo(0, top.offset().top - howMuchFromTop)
          })

          .invisible {
          visibility:hidden;
          height:0px;
          margin:0 !important;
          padding:0 !important;
          border-width:0 !important;
          min-height:0 !important;
          }

          div {
          background: #cccaaa;
          height: 110px;
          margin: 4px 0 0 0;
          }

          .red {
          background: red;
          }


          #toggle {
          position: fixed;
          top: 0;
          left: 0;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div>1</div>
          <div>2</div>
          <div class="invisible">3</div>
          <div class="invisible">4</div>
          <div>5</div>
          <div class="invisible">6</div>
          <div>7</div>
          <div class="invisible">8</div>
          <div>9</div>
          <div>10</div>
          <div>11</div>
          <div>12</div>
          <div class="invisible">13</div>
          <div class="invisible">14</div>
          <div class="invisible">15</div>
          <div>16</div>
          <div>17</div>
          <div>18</div>
          <div>19</div>
          <div>20</div>
          <div>21</div>
          <div>22</div>


          <button id="toggle">toggle</button>






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 21 '18 at 21:10

























          answered Nov 21 '18 at 21:01









          enapupeenapupe

          4,53711326




          4,53711326








          • 1





            Wow, this is super-awesome, thanks a lot! elementFromPoint() was what I was missing, goot to know that one.

            – PhilippG
            Nov 21 '18 at 21:10











          • Glad it works for you. As for browser support it seems to be fine caniuse.com/#feat=element-from-point

            – enapupe
            Nov 21 '18 at 21:12
















          • 1





            Wow, this is super-awesome, thanks a lot! elementFromPoint() was what I was missing, goot to know that one.

            – PhilippG
            Nov 21 '18 at 21:10











          • Glad it works for you. As for browser support it seems to be fine caniuse.com/#feat=element-from-point

            – enapupe
            Nov 21 '18 at 21:12










          1




          1





          Wow, this is super-awesome, thanks a lot! elementFromPoint() was what I was missing, goot to know that one.

          – PhilippG
          Nov 21 '18 at 21:10





          Wow, this is super-awesome, thanks a lot! elementFromPoint() was what I was missing, goot to know that one.

          – PhilippG
          Nov 21 '18 at 21:10













          Glad it works for you. As for browser support it seems to be fine caniuse.com/#feat=element-from-point

          – enapupe
          Nov 21 '18 at 21:12







          Glad it works for you. As for browser support it seems to be fine caniuse.com/#feat=element-from-point

          – enapupe
          Nov 21 '18 at 21:12






















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419970%2fkeep-scroll-position-when-elements-above-toggle-visible-invisible%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          MongoDB - Not Authorized To Execute Command

          How to fix TextFormField cause rebuild widget in Flutter

          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith