0

I'm struggling to find a way to move my scroll position on the bottom of some elements that i've prepended in html.

This is the code i use to prepend my data:

var id = '#posts'+(yy-2);
$.get('page-'+(yy-1) , function(data){
     var content = $(data).find(id);
     $('#container').prepend(content);                           
});

I have to move the scroll position under 'content'. I've tried adding:

$('html, body').scrollTop('#posts'+(yy-1));

But it doesn't do anything

Tammapao01
  • 23
  • 6
  • 1
    Check `scrollIntoView` method https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView – Jan Pfeifer Jan 16 '23 at 10:05
  • Do you mean move the _bottom of your viewport_ to the bottom of the element? The scroll position is the top of the view port; if you align _that_ to the bottom of some element, the element would be off-screen. What have you tried? Google yields this, for example: [How do I get an element to scroll into view, using jQuery?](/q/4884839/4642212). – Sebastian Simon Jan 16 '23 at 10:06
  • @SebastianSimon when i click a button this function get started and it prepends some elements to my existing elements, the thing is that when i prepend those elements my scroll position stays on top of the prepended elements, but i need to get moved on the bottom of those elements – Tammapao01 Jan 16 '23 at 10:12

1 Answers1

0

To answer the question "How to move the scroll position on the bottom of prepended elements in jquery?"

https://api.jquery.com/scrolltop/

.scrollTop( value ) Returns: jQuery

Description: Set the current vertical position of the scroll bar for each of the set of matched elements.

scrollTop( value )
    value
    Type: Number
    A number indicating the new position to set the scroll bar to.

The vertical scroll position is the same as the number of pixels that are hidden from view above the scrollable area. Setting the scrollTop positions the vertical scroll of each matched element.

In other words you are setting the scrollbar of a scrollable element. Since your #container is expected to contain the posts with no overflow hidden, that's not strictly a scrollable area and your only one is the whole window (html).

When you did $('html, body').scrollTop('#posts'+(yy-1)); it was equivalent to actually doing this $('html').scrollTop(0).

But a working strategy might be to get the position.y and height of the element just prepended, and set the scrollbar to a number being the sum of those two values.

  const $post = createPost();  
  
  $('#posts').prepend($post);                           
 
  //y = $post vertical position
  const y = $post.position().top;
  //h = $post height
  const h = $post.height();
  
  //scroll the scrollable area to y+h (bottom of the latest div prepended)
  $('html').scrollTop(y+h);

I made a demo where you have a posts container #posts and a button at the bottom that will prepend a new post at the beginning of the list, and one moment later will move the window scroll position to the "bottom of the prepended element".

But confused...

I'm still a bit confused on why you needed to scroll at the bottom of the latest prepended post. It doesn't click to me and that's why I quoted your textual question to my proposed solution.

function createPost(){
  const $post = $('<div>');
  $post.addClass('post');
  const i = $('#posts > .post').length;
  const body = `This is a dynamic post #${i+1}`;
  $post.text(body);  
  return $post;
}

function prependPost(){
  const $post = createPost();  
  
  $('#posts').prepend($post);                           
 
  //y = $post vertical position
  const y = $post.position().top;
  //h = $post height
  const h = $post.height();
  
  //scroll the scrollable area to y+h (bottom of the latest div prepended)
  $('html').scrollTop(y+h);
}
body{
  padding: 3em;
}

h1{
  text-align: center;
  font-size: 4rem;
  border-bottom: solid 3px lightgray;
}

#posts{
  display: flex;
  flex-direction: column;
  gap: 1em;
  
  border: dashed 3px lightgray;
  padding: 1em;
  margin-bottom: 1em;    
}

.post{
  height: 10em;
  border: solid 1px lightgray;    
  padding: 1em;
}

button{
  padding: 1em 1em;
  width: 100%;
  font-weight: 600;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<h1>Posts:</h1>

<div id="posts">
  <div class="post">This is a static post #1</div>
  <div class="post">This is a static post #2</div>
  <div class="post">This is a static post #3</div>
</div>

<button
  type="button"
  onclick="prependPost();">PREPEND POST</button>
Diego D
  • 6,156
  • 2
  • 17
  • 30
  • this is exactly what i needed, my button will be on top of the posts, this will be needed for all the pages that are different from page1, so if a user goes from an external link to page2 you can see the posts from page 1 clicking the button on top, but wanting to give an idea of scroll i needed that my prepended posts must be on the top of the view, so the user can scroll up having the prepended posts – Tammapao01 Jan 16 '23 at 12:10
  • 1
    ok then, glad it worked as expected – Diego D Jan 16 '23 at 12:17