Am looking for something similar to scrollIntoView()
within Ionic2 to use when I click on a button, for example.
None of the methods detailed in ion-content
help.
Please take a look at this working plunker
You can use the scrollTo(x,y,duration)
method (docs).
The code is pretty simple, first we obtain the position of the target element (a <p></p>
in this case) and then we use that in the scrollTo(...)
method. First the view:
<ion-header>
<ion-navbar primary>
<ion-title>
<span>My App</span>
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<button ion-button text-only (click)="scrollElement()">Click me</button>
<div style="height: 600px;"></div>
<!-- Notice the #target in the p element -->
<p #target>Secret message!</p>
<div style="height: 600px;"></div>
</ion-content>
And the component code:
import { ViewChild, Component } from '@angular/core';
import { NavController, Content } from 'ionic-angular';
@Component({
templateUrl:"home.html"
})
export class HomePage {
@ViewChild(Content) content: Content;
@ViewChild('target') target: any;
constructor() { }
public scrollElement() {
// Avoid reading the DOM directly, by using ViewChild and the target reference
this.content.scrollTo(0, this.target.nativeElement.offsetTop, 500);
}
}
The ion-content should have methods for scrolling to particular child elements, however deep. The current methods are okay, but one perspective of the purpose of ionic is to make laborious, boring code like document.getElementById
obsolete.
The methods also lack control over the scroll animation.
Hence currently the best option is the scrollIntoView
method. Attach an id to the element you wish to scroll to, then use getElementbyID to call scrollIntoView. So:
.html
...
<ion-row id="myElement">
...
</ion-row>
ts
...
scrollToMyElement() {
document.getElementById('myElement').scrollIntoView({
behavior: 'smooth',
block: 'center'
});
}
Then call the method on some DOM event or button click. If your element is conditional this will likely not work. Instead use a conditional hidden attribute or, if you must use ngIf, time the logic as such that the element is inserted first.
I've tried this with various other ionic (4) UI components and it works fine.
For Ionic-4 there are multiple changes in the terms used
Here is the code modified of the accepted answer for ionic-4
<ion-header>
<ion-navbar primary>
<ion-title>
<span>My App</span>
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<button ion-button text-only (click)="scrollElement(target)">Click me</button>
<div style="height: 600px;"></div>
<!-- Notice the #target in the p element -->
<p #target>Secret message!</p>
<div style="height: 600px;"></div>
</ion-content>
component Code :
import { ViewChild, Component } from '@angular/core';
import { IonContent } from '@ionic/angular'; // change-1
@Component({
templateUrl:"home.html"
})
export class HomePage {
@ViewChild('target', { static: false }) target: ElementRef;
@ViewChild('ion_content', { static: false }) ionContent: IonContent; //change-2 for angular > 8.0 remove this for angular 6.x
constructor() { }
public scrollElement($target) {
this.ionContent.scrollToPoint(0, $target.offsetTop, 500);
//$target (prefered if you have multiple scroll target) could be this.target.nativeElement
}
}
I'd use an anker link in HTML.
Just give the elemnt and id="scrollXYZ" and wrap the button in an
Example:
<a href="#scrollXYZ"><button>Example</button></a>
<div id="scrollXYZ"><h2>Scroll to this</h2></div>
I noticed the above solution don't work well with Angular Universal server-side rendering (SSR) due to document
not being available server-side.
Hence I wrote a convenient plugin to achieve scrolling to elements in Angular 4+ that work with AoT
and SSR
NPM
ngx-scroll-to
GitHub
ngx-scroll-to
I was trying to do this in Ionic 3 and due to the fact that <Element>.offsetTop
was returning10
(the padding on the top of the element) instead of the distance to the top of the page (much larger unknown number) I ending up just using <Element>.scrollIntoView()
, which worked well for me.
To get the <Element>
object I used document.getElementById()
, but there are many other options on how to get a handle on that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With