I'm working on an Ionic 6 Webapp based on Angular 13. The client's QA-department want's to perform regression-testing via Selenium test-automatization. For other project's they used window.scrollBy(0, window.innerHeight) to systematically scroll over the page and take screenshots to find regression issues. But this is not possible on Ionic pages, since the HTML body is not scrollable, only the content of the ion-content element. Is there any way to trigger scrolling within the ion-content element via simple JavaScript? I created a Stackblitz where you can see the basic structure of my ionic-page.
So far I tried different things but none worked:
document.getElementsByTagName("ion-content")[0].scrollTo(0, 300);
document.getElementsByTagName("ion-content")[0].scrollToBottom();
document.getElementsByTagName("ion-content")[0].shadowRoot.childNodes[1].scrollTo(0, 300); //tried to access the inner-scroll div
document.getElementsByTagName("ion-content")[0].shadowRoot.childNodes[1].scrollToBottom(); //tried to access the inner-scroll div
why do you want JavaScript to scroll when ionic and angular have a better way to scroll. please check the stackblitz link I have done some code in it.
HTML
<ion-app>
<ion-header>Demo Header</ion-header>
<ion-content>
<div class="large-content-div"></div>
<p id="scrollMe">Scroll to find me</p>
</ion-content>
<ion-footer>Demo footer</ion-footer>
</ion-app>
TS File
export class AppComponent {
name = 'Ionic 6 Angular ' + VERSION.major;
constructor() {
setTimeout(() => {
this.scrollToBottom();
}, 5000);
}
scrollToBottom(): void {
try {
document.querySelector('#scrollMe').scrollIntoView({
behavior: 'smooth',
});
} catch (err) {}
}
}
Here, I have given both the solution if you want to scroll to the bottom scrollToBottom() method or you want to scrollTo some division points scrollTo() method, use it as per the requirement.
This is the best way to call scroll Event in Ionic/Angular
Related
i have this really annoying problem in my Ionic 4 application that when I change page the screen reader focus is at the bottom of the page which means that my users will have to reverse through the content to get to my main content section.
i did some research and this seems to be a problem with Angular Angular accessibility documentation
Here they suggest that you should set focus on the main content.
However when I attempt this using:
ionViewDidEnter() {
const mainHeader = document.querySelector('#mainContent');
if (mainHeader) {
(mainHeader as HTMLElement)?.focus();
}
}
it doesn't really do anything.
Has anyone had a similar issue and know how I might fix it?
Edit
I have also tried with the viewChild:
#ViewChild('mainPage') mainContent: ElementRef;
ngOnInit() {
this.router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
this.mainContent.nativeElement.focus();
});
}
And setting the mainPage element's tabIndex=0:
<div #mainPage tabindex="0"><ion-router-outlet main></ion-router-outlet></div>
Yet still no focus.
I want to execute a function when the scrollbar reaches the bottom of the page.
How do I know if the scroll has reached the end of the page?
#HostListener("window:scroll", [])
onScroll(): void {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
console.log('end')
}
}
but it not work .
How can i do this work ????
Using that example is pretty easy. You can use the code inside the component's .ts file to use it. Check out this demo on CodeSandBox. I have implemented the fiddle in angular.
Here you can see the full-screen preview of the demo.
I am doing an app in Ionic 3 and using infiniteScroll inside a and . I see common issues in github and even here in SO. But most of it has no solution.
The problem is when the page is loaded and render all the data that is paginated from the backend when I get an API request. Now I had a infiniteScroll event when I scroll to the bottom part of my page. But the problem is that it only trigger once and load my data. If I want to load a new one I have to go back at the top of the content and go down again to load some data.
Here is my code in my typescript file below:
I used a viewChild for Scroll native element of Ionic inside my <ion-slide>
Here is the structure of my html below:
<ion-slide *ngIf="!preloader">
<ion-scroll #scrollWeb scrollY="true">
<! -- Content Part for loop of an array with data from a server -->
<!-- Load more for following -->
<ion-infinite-scroll *ngIf="selectedSegment == 'first' && !pulling" (ionInfinite)="loadMorePost($event)">
<ion-infinite-scroll-content
loadingSpinner="crescent"
loadingText="Loading more post..."
>
</ion-infinite-scroll-content>
</ion-infinite-scroll>
<small *ngIf="noMorePostToShowForExplore">No more post to show</small>
</ion-scroll>
</ion-slide>
And the typescript
loadMorePost(infiniteScroll? :any) {
console.log('Async operation begun')
setTimeout(() => {
if (this.selectedSegment == 'first') this.loadMoreExplore()
else this.loadMoreFollowing()
infiniteScroll.complete();
}, 1000);
}
As I have said earlier about the viewChild I tried to trigger the y-axis scroll and only allow to refresh if it is at the most bottom part of the page. Which is still not working.
this.scrollWeb.addScrollEventListener((ev) => {
if ((ev.target.offsetHeight + ev.target.scrollTop) >= ev.target.scrollHeight) {
// this.loadMorePost(InfiniteScroll)
console.log('Loading post')
}
})
Appreciate if someone could help.
Thanks in advance.
website in question
OK, i don't understand javascript or jquery so, i pose this question to you guys.
I am working on courses from FreeCodeCamp and i created a one page site that worked well in codepen. but, since i already owned a domain/hosting i moved it over (and with some extra work got it to work properly).
My issue currently is with the navbar.
On the index.html it works properly. (when targeting jumplinks on the index.html page) it scrolls down to it and gives enough space above the h1 tags so they don't get behind the navbar.
I wanted to add another link to my page for my resume (which wouldn't work with the current javascript) so i had to add a class to each of the links in my navbar that were targeting ids on the index page, and updated my javascript from it targeting all the a tags to just the a tags with the class=jumps.
So, i thought my issue was fixed, until i went to my second page xp.html.
i changed the links in the navbar to be <a href="index.html#about> so that it would (hopefully) go to the index page and then jump down to the right section of the page with the jump link. but, that didn't work. it would just stay on my xp page.
So, i took the code out of the main.js file and into a index.js file, and linked it only to the index page. which allows me to now navigate properly between my two pages and the jump links, but if you are on the xp page and you click one of the jump link links, it now makes the h1 text go behind the navbar.
I hope this explanation is good?
So, i'm needing help to fix the current issue of my headers going behind my navbar when coming from my xp page (or other pages i add in the future)
I would really appreciate help with this!
using css and jQuery(index.js)
add a custom css in you main.css .pad-top{ padding-top:5%;} and add this in your html like this see the class
<div id="webfolio" class="row c-wrapper smooth nomargin pad-top">
and in your jQuery(index.js) replace the .top - 80 with 5
And If you use only jQuery(index.js) (If you want you can short this Query but I just share the full for understanding )
function anchorScroll(fragment) {
"use strict";
var amount, ttarget;
amount = $('nav').height();
ttarget = $('#' + fragment);
$('html,body').animate({ scrollTop: ttarget.offset().top - amount }, 1000);
return false;
}
function outsideToHash() {
"use strict";
var fragment;
if (window.location.hash) {
fragment = window.location.hash.substring(1);
anchorScroll(fragment);
}
}
function insideToHash(nnode) {
"use strict";
var fragment;
fragment = $(nnode).attr('href').substring(1);
anchorScroll(fragment);
}
$(document).ready(function () {
"use strict";
$("a[href^='#']").bind('click', function () {insideToHash(this); });
outsideToHash();
});
I have seen a lot of websites which "wrapper" width is 960px. As a background image they have an image which is clickable (some kind of advertise) and the whole webpage is over that image, like on this site.
Can you give me tutorial or something on that ?
Tom's code was a huge help, but I needed pointer cursor for this type of ad, but not for all the site, so I came up with this solution:
$('body').bind('click', function(e) {
if ($(e.target).closest('#container').size() == 0) {
alert('click');
}
}).bind('mouseover', function(e) {
if ($(e.target).closest('#container').size() == 0) {
$(this).css('cursor','pointer');
} else {
$(this).css('cursor','default');
}
});
In the first place you put the ad image as the website background then basically you have to capture the click on the whole body and check if it was in-or-outside of the page content. To do that you have to check if the event target element have the content wrapper (or wrappers if there are multiple) as one of its parent nodes - if not it means the click was outside of the page content.
If you'd like to do it here on StackOverflow you could do it with this bit of code.
$('body').bind('click', function(e){
if(!$(e.target).closest('#content').length) {
alert('ad outside content clicked');
}
});
Feel free to try it in your javascript console - SO is using jQuery so it will work - when you will click outside of the content area (at the edges of the screen) you will get alert that ad was clicked.
You'd obviously have to replace the alert with any kind of callback you'd have for your commercial - opening a new web page or whatever
Hope that helps
Tom
ps.
Keep in mind that this example is using jQuery for simplicity not native JS so you'd need the library for it to work.