Scroll to top of the HTML page whenever refresh the page - javascript

I am fighting with a small issue for a few hours.
I am working on Angular-9, in the HTML page, I have a very long table(500 rows data). when I going to the bottom of the table and then refresh the page, it will be on the bottom of the page. not scrolling to the top of the page.
but whenever I refresh the page, the page should go to the top of the HTML page(top of the table).
Actually, I have searched a lot of google solutions, but no one is work.
Can u please suggest how to resolve this?

Add this in js file.
$(this).scrollTop(0);

If you have a header component you can directly try this, or just make a empty div at the top of the page with id header and paste this in your main function.
Make sure of the ID or it will not work.
const header= document.getElementById('#header');
header.scrollIntoView();

On your template, add a template variable to your scrollable container like this:
<div #myScrollableContainer>
<!-- Here is your content that scrolls -->
</div>
And on your component get that one with #ViewChild and set the scrollTop on that.
#Component({ /*...*/ })
export class MyComponent {
// pass the name of the template variable you picked with # on your template
#ViewChild('myScrollableContainer') private myContainer:ElementRef<HTMLDivElement>;
// Call this when you want to scroll to top
public scrollToTopOfScrollable():void {
this.myContainer.nativeElement.scrollTop = 0;
}
}

Related

Return to top of page on RouterLink

I will preface this by saying that there are several answers online for this exact same purpose with an Angular app. However, none of these appear to be working for me.
I have so far tried nearly everything from these issues
1 , 2 , 3 , 4 and a couple of other but I am still not getting the correct behavior.
Currently, if I am scrolled down and viewing a route, then I click on the item to view a new route via routerLink, the page stays in the same position. This causes some issues especially when on a smaller screen or when looking down a long list of items.
In the current app, my AppComponent is as follows (I am using Angular Material):
<app-header></app-header>
<mat-sidenav-container class="main-sidenav">
<mat-sidenav class="sidenav"#sidenav [mode]="mode" [opened]="openSidenav">
<app-sidenav></app-sidenav>
</mat-sidenav>
<mat-sidenav-content>
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>
The router-outlet is displaying one of the following:
A workout page with a list and filter
A workout "detail page" that shows the workout description
In the workout list, when an item is clicked, it has a routerLink: <a [routerLink]="[i]"> where i is the index of the current workout coming from an array (from a firebase database in my case).
Here is the stackblitz to this code. The workouts-page can be found at src/app/features/workouts-page/ and then the workout-list, workout-filter, and workout-detail showing up accordingly. However, when clicked on the routerLink, the scroll position stays the same on the workout detail page.
Since Angular 6+, the recommended method has been to use, within your routing module:
...
imports: [RouterModule.forRoot(routes,{scrollPositionRestoration: 'top'})
...
At the same time, you could also use "enabled" and get the same result. This does not change any behavior in the application I am running. Furthermore, I have tried a few "work-arounds" such as adding the following to my main component:
export class MyAppComponent implements OnInit {
constructor(private router: Router) { }
ngOnInit() {
this.router.events.subscribe((evt) => {
if (!(evt instanceof NavigationEnd)) {
return;
}
window.scrollTo(0, 0)
});
}
}
This workaround and many others have once again not changed the behavior and it leaves the page in the same scroll position as before the router was clicked. One different method from the GitHub request is to add an (activate)="onActivate($event) to the <router-outlet>, where the function runs window.scrollTo(0, 0);. Still, this doesn't seem to be working. I can even put the window.scrollTo(0,0) or scrollTop() in the ngOnInit of any component related to the router outlet, and you guessed it, still no change.
I figured this had to do with the css of the page altogether so I changed my body and html positioning as mentioned in stack overflow issues with the same end result.
Is there a way that I can "reset" the scroll position when a route is clicked with the routerLink property so the page doesn't stay in the same scrolled position when the route is loaded?
ScrollPositionRestoration works properly with full page scroll (body getting scrolled).
In your case internal divs are scrollable. To restore scroll for those you need to customize the scroll restore process.
Here is a blog link which talks about the same https://www.bennadel.com/blog/3534-restoring-and-resetting-the-scroll-position-using-the-navigationstart-event-in-angular-7-0-4.htm
Base idea is to storage scroll position before navigation and restore them if you visit the page due to pop state.
Nikhil gave a method for the ScrollPositionRestoration and helped me find the reason this wasn't working, but I ended up finding a way to do this with a simple activate function.
Like he mentioned, the reason this wasn't working is due to the "body" being reset on the scroll. Since the fixed header was at the top of the body, it was already in the "top" scroll position all the time. To fix this, I added the following simple code:
In the AppComponent HTML
...
<mat-sidenav-content id="detail">
<router-outlet (activate)="resetPosition();"></router-outlet>
</mat-sidenav-content>
...
Note, the (activate)="resetPosition(); causes the function to run any time a router is activated (or any time you go to a new router). Here is the function added to the app.component.ts:
AppComponent TS
resetPosition() {
let myDiv = document.getElementById("detail");
myDiv.scrollTop = 0;
}
This takes the id="detail" from the html container and then sets the scroll position to the top of this div rather than the entire body which was already at the top.

Hash url and AngularJS

I am using angularjs for part of my page say single component, which is used in many pages.Now my problem is hash url does not work now.
Example: I have a div#hello in my page and URL is given as Url#hello.but it does not go to that particular div just the top of the page is diaplayed.
So could you guys help me here please?
NOTE:The url#hello is changing to url/#hello.The page cannot be changed to angular and only that single component use angular.
EDIT: Thank you Stephen:) yes, of course, we need to use routing.The thing is, after page load, if we change the url back to URL#hello it works.So is it possible to do it in other way apart from Routing and $angularscroll ?(i.e) just from the JS or jQuery perspective ?
Ok, thanks. I've misunderstood you. I think I have a better understanding now. Please correct me if I am wrong:
So, you're essentially trying to make a hello link that points to a section within the same page. When you change the url to pageUrl#hello the page should jump down to the section with the id called hello.
But the problem is that since your section has an AngularJS component that uses the ngRoute module, this routing functionality is making your page redirect to pageUrl/#hello instead of jumping to the HTML section with the id='hello'.
Is this correct?
Solution
If I understand your problem correctly, the solution is to check if your ng-app='appName' attribute is on the body tag. If it is, then move it down to your component's parent element.
If a hash link is a child of the ng-app element, then when you click it AngularJS thinks you want to redirect to another view. This is what causes the Home link to redirect to pageUrl#/home.
<body ng-app="demoApp">
Hello <!-- redirects to #/hello -->
<div id="hello"></div>
<!-- ... -->
So if you put the hash link outside of the ng-app element then it will behave as expected when you click it.
<body>
Hello <!-- jumps to the 'hello' div -->
<div id="hello" ng-app="demoApp"></div>
<!-- ... -->
On Page Load
If you want the page to jump to the hello div on page load, then set window.location = '#hello' inside your controller. Then, when you visit pageUrl#hello, the hello div should appear instead of the top of the page.
If you don't have a controller, or don't want to use one, then after your document loads, check the hash url and change it programmatically.
$(document).ready(function(){
if(window.location.hash == '#hello'){
window.location = '#hello';
}
})

Changing HTML content on menu item click

I am trying to change the content of the yellow area when the user clicks on 'Dashboard', 'customers' etc: Here is the template I used
First I tried to change index.js I gave an id to div area:
$('.icon-dashboard').on('click', function() {
$("#area").load("secondpage.html #area > *");
});
This didn't work for me. Any suggestions to change the content between main tags?
Your selector for the load command is wrong. Your HTML shows a <main> tag with <div class="helper"> so you would want to use $("main .helper").load(...) to load content into "helper". Or, if you want to replace the "helper" div with whatever comes back from .load, just do $("main").load(...).
Also, passing "secondpage.html" to .load() is only going to work in the local browser. I'm assuming you're only doing that because you're testing? Ultimately, you'll need some backend script at an URL to return your content.

Remove "page jumpyness" when moving a page element via jquery

Just as a little pre-info, I'm running a Volusion e-commerce site that has internal page HTML locked down, so I am unable to add any ID's or classes to internal page elements.
The default HTML provided by Volusion puts a table out of order for my design on my category pages. I have a bit of script that targets that table on my product category pages, and moves it. The problem is that the script is run after the page is loaded, causing a "jumping" effect as the table is moved via jquery.
The simple solution would be to hide the table first via css, and then have the jquery show the element after it has been moved, however, I am unaware of how to accomplish this.
Here is the moving script. It first detects if the user is on a category page via a URL check. It then finds the first child table inside the #content_area element, and moves it.
<script type='text/javascript'>
$(function () {
if (location.pathname.indexOf("-s/") != -1) {
var table_to_move = $("#content_area").find("table").first();
$("#content_area").find("form").before(table_to_move).show();
$('#jmenuhide').insertBefore('.refinement_price_section');
}
else {
}
});
</script>
I have tried targeting the element via css, and hiding it, and then re-showing it after the script has run. However, since I can only reference it through css selectors, and not an ID or class, the page will end up hiding the wrong table, as the table orders change when the script is run.
Anyone have any idea how I can smooth out this table movement? Thanks!
You can view this script in action at: http://www.yandasmusic.com/Folk-Instruments-s/1821.htm

Static content in website

I've got a website and I'd like to make a part of it static. What happens is that the header, the menu bar and the footer are consistent in every page. I'd like to have them always loaded and when I click the menu button, it will only reload what is the body of the site.
Is there a simple chunck of code that can early achieve this? Something in js or ajax? I'm sorry but I don't have enough experience in these languages to accomplish something on my own. I've already tried to check jQuery library but it's still pretty confusing to me.
Thank you.
I think you don't even need Ajax or css!! Just use iFrames!! They are awesome, what happens is that u only design one page as the holder of your static content (Header-Menu ...) and put one iFrame in there as a place holder for any page you want to load in it, u should use proper css code to place the iFrame where you want, now, for every link in your menu, just set the "target" attribute equal to your iFrame's name and all the links will be loaded in that iFrame and your page won't be reloaded with every link click... I'll be back with some code...
Just add in every page a div container with ID for header, menubar and footer and just load it with this:
$(document).ready(function(){
$('#header').load('header.html');
$('#menubar').load('menubar.html');
$('#footer').load('footer.html');
});
Just make sure that the html files don't have html, head or body tags within, only the HTML-Code you would write inside the div. It's just like the include function in PHP.
EDIT:
For easy and simple implementation store the code above inside a .js file (e.g. include.js) and add this inside every head just below the include of all other scripts of your html files:
<script type="text/javascript" src="include.js"></script>
EDIT2:
Another solution ist to load the content of the page instead of the header, menubar, footer.
Here you take the same specifications (no html, body, etc. tags inside your content html files)
Name your content div e.g. <div id="content"></div>
Your navbar for example:
<div id="navbar">
Content1
Content2
</div>
JavaScript Code:
$(document).ready(function() {
//Click on a link that's child of the navbar
$('#navbar > a').click(function() {
//Get the html file (e.g. content1.html)
var file = $(this).attr('href');
//Load this file into the #content
$('#content').load(file);
return false;
});
});
You should consider the use of Server Side Included : http://httpd.apache.org/docs/current/howto/ssi.html
It's not quite easy to understand (as it refer to apache configuration), but this is a really great solution.
In a nutshell, you include parts of html code in you main page :
<!--#include virtual="/footer.html" -->
You won't have to use or understand all JQuery Framewol, user agent won't have to parse (if they are able to !) Javascript.
This is a pretty good replacement of PHP / ASP / Java for this kind of purpose.
You could use ajax to request the body of each page. But this is only one possibility - there are many. An other approach could be to create you page content using a script language (php, perl) serverside and employ a function there which adds footer, header and anything else to each page.
If you have an idea of Jquery then use click event on menu links to load the page in a div like the following syntax may help you.
$(document).ready(function(){
$("a.menu").click(function(){
$("#bodyContent").load("http://abc.com/your-linked-page.html");
});
});
To load the url dynamically use the following code:
In your menu bar the link looks like:
Home
In your Jquery code:
$(document).ready(function(){
$("a.menu").click(function(){
url = $(this).attr("title"); // here url is just a variable
$("#bodyContent").load(url);
});
});
Step 1: Add Jquery file into your html page.
Step 2: Use the above jquery code and change your menu link to the new what i said here.
Step 3: If you done it correctly, It will work for you.
How about a traditional iframe?
In your menu:
<a target="body" href="URL_to_your_Menu1_page">Menu1</a>
and then further in the document:
<iframe name="body" src="URL_to_homepage"></iframe>
You may use frameset and frames and organize you pages accordingly. So, frames containing menus can always be at display and while displaying contents on click of menu u may set target to frame in which you would like to load the contents.

Categories