Add mutation observer to handle active text in scrolling section

This commit is contained in:
Konstantinos Triantafyllou 2022-05-05 10:44:00 +03:00
parent eaaa4b863c
commit cfaffcc271
4 changed files with 106 additions and 101 deletions

View File

@ -18,7 +18,7 @@
background-size: 25%;
}
#contact-us .left img {
.contact-us .left img {
position: absolute;
top: 0;
left: 0;
@ -29,7 +29,7 @@
transform: matrix(1, -0.07, 0.07, 1, 0, 0);
}
#contact-us .right img {
.contact-us .right img {
position: absolute;
bottom: 0;
right: 0;

View File

@ -26,14 +26,14 @@
</div>
<ng-template #scrolling_text let-position_class="position_class">
<div [class]="position_class" uk-parallax="target: #js-sticky-parallax-images-all; start: 100vh; end: 100% + 100vh - 150vh; opacity: 0,1 20%,1 80%,0">
<div #scrolling_element [class]="position_class" uk-parallax="target: #js-sticky-parallax-images-all; start: 100vh; end: 100% + 100vh - 150vh; opacity: 0,1 20%,1 80%,0">
<h3 class="uk-h2">
Get a <span class="uk-text-primary">360° view <br> of research results.</span>
</h3>
<p class="uk-text-large">Track and discover your organizations research output. <br> Use the OpenAIRE Research
Graph to view your publications-data-code <br> and how they interconnect.</p>
</div>
<div [class]="position_class" uk-parallax="target: #js-sticky-parallax-images-all; start: 150vh; end: 100% + 100vh - 200vh; opacity: 0,1 20%,1 80%,0">
<div #scrolling_element [class]="position_class" uk-parallax="target: #js-sticky-parallax-images-all; start: 150vh; end: 100% + 100vh - 200vh; opacity: 0,1 20%,1 80%,0">
<h3 class="uk-h2">
Monitor <span class="uk-text-primary">Open Science <br></span> compliance<span
class="uk-text-primary">.</span>
@ -41,7 +41,7 @@
<p class="uk-text-large"> Work with the Open Science expert community <br> for open and transparent metrics.
Discover Open <br> Science trends for your organization. See how <br> you fare in European Open Science Cloud.</p>
</div>
<div [class]="position_class" uk-parallax="target: #js-sticky-parallax-images-all; start: 200vh; end: 100% + 100vh - 250vh; opacity: 0,1 20%,1">
<div #scrolling_element [class]="position_class" uk-parallax="target: #js-sticky-parallax-images-all; start: 200vh; end: 100% + 100vh - 250vh; opacity: 0,1 20%,1">
<h3 class="uk-h2">
Turn <span class="uk-text-primary">research <br> results </span> to insights<span
class="uk-text-primary">.</span>
@ -280,7 +280,7 @@
</ng-template>
</div>
</div>
<div id="contact-us" class="uk-section uk-container uk-container-large uk-margin-large-bottom">
<div #contact class="uk-section uk-container uk-container-large uk-margin-large-bottom contact-us">
<div class="uk-grid" uk-grid>
<div class="left uk-position-relative uk-width-1-1 uk-width-1-5@m">
<img class="uk-box-shadow-large" src="assets/monitor-assets/avatar2.jpg">

View File

@ -1,4 +1,13 @@
import {Component, ViewChild, OnDestroy, AfterViewInit} from '@angular/core';
import {
Component,
ViewChild,
OnDestroy,
AfterViewInit,
ElementRef,
ViewChildren,
QueryList,
OnInit
} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Meta, Title} from '@angular/platform-browser';
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
@ -20,13 +29,14 @@ import {properties} from "../../environments/environment";
import {Subscriber} from "rxjs";
import {QuickContactService} from '../openaireLibrary/sharedComponents/quick-contact/quick-contact.service';
import {CanExitGuard, IDeactivateComponent} from "../openaireLibrary/utils/can-exit.guard";
import {element} from "protractor";
@Component({
selector: 'home',
templateUrl: 'home.component.html',
styleUrls: ['home.component.css']
})
export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateComponent {
export class HomeComponent implements OnInit, OnDestroy, AfterViewInit, IDeactivateComponent {
public pageTitle = "OpenAIRE | Monitor";
public description = "OpenAIRE - Monitor, A new era of monitoring research. Open data. Open methodologies. Work together with us to view, understand and visualize research statistics and indicators.";
public stakeholders: StakeholderInfo[] = [];
@ -44,22 +54,20 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
public loading: boolean = true;
public errorCodes: ErrorCodes;
public properties: EnvProperties = properties;
/* Section scroll Map */
public map: Map<string, string> = new Map<string, string>([['1st', 'ipad'], ['2nd', 'ipad'], ['3rd', 'ipad']])
public type: string = null;
public directLink: boolean = true;
public publicationsSize: any = null;
public datasetsSize: any = null;
public softwareSize: any = null;
public otherSize: any = null;
public fundersSize: any = null;
public showQuickContact: boolean = true;
public showQuickContact: boolean = true;
@ViewChild('AlertModal') modal;
private errorMessages: ErrorMessagesComponent;
private subscriptions = [];
private user: User;
private observer: IntersectionObserver = null;
@ViewChildren('scrolling_element') elements: QueryList<ElementRef>;
@ViewChild('contact') contact: ElementRef;
constructor(
private route: ActivatedRoute,
private _router: Router,
@ -72,8 +80,8 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
private helper: HelperService,
private seoService: SEOService,
private _refineFieldResultsService: RefineFieldResultsService,
private _searchResearchResultsService: SearchResearchResultsService,
private quickContactService: QuickContactService) {
private _searchResearchResultsService: SearchResearchResultsService,
private quickContactService: QuickContactService) {
this._meta.updateTag({content: this.description}, "name='description'");
this._meta.updateTag({content: this.description}, "property='og:description'");
this._meta.updateTag({content: this.pageTitle}, "property='og:title'");
@ -82,7 +90,7 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
this.errorMessages = new ErrorMessagesComponent();
this.status = this.errorCodes.LOADING;
}
public ngOnInit() {
let url = this.properties.domain + this.properties.baseLink + this._router.url;
this.seoService.createLinkForCanonicalURL(url, false);
@ -101,55 +109,68 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
}
canExit(): boolean {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
if (this.observer) {
this.observer.disconnect();
}
this.clear();
return true;
}
OnDestroy() {
ngOnDestroy() {
this.clear();
}
clear() {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
} else if (value instanceof IntersectionObserver || value instanceof MutationObserver) {
value.disconnect();
}
});
if (this.observer) {
this.observer.disconnect();
}
}
ngAfterViewInit() {
if (typeof document !== "undefined") {
this.createObserver();
}
ngAfterViewInit() {
this.createObservers();
}
createObserver() {
let target = document.querySelector('#contact-us');
let options = {
root: null,
rootMargin: '200px',
threshold: 1.0
};
this.observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if(entry.isIntersecting && this.showQuickContact) {
this.showQuickContact = false;
this.quickContactService.setDisplay(this.showQuickContact);
} else if(!entry.isIntersecting && !this.showQuickContact) {
this.showQuickContact = true;
this.quickContactService.setDisplay(this.showQuickContact);
}
})
}, options);
this.observer.observe(target);
}
createObservers() {
let options = {
root: null,
rootMargin: '200px',
threshold: 1.0
};
let intersectionObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting && this.showQuickContact) {
this.showQuickContact = false;
this.quickContactService.setDisplay(this.showQuickContact);
} else if (!entry.isIntersecting && !this.showQuickContact) {
this.showQuickContact = true;
this.quickContactService.setDisplay(this.showQuickContact);
}
});
}, options);
intersectionObserver.observe(this.contact.nativeElement);
let mutationObserver = new MutationObserver(entries => {
entries.forEach(entry => {
if (entry.attributeName === 'style') {
let opacities: number[] = this.elements.map(element => +element.nativeElement.style.opacity);
let active: number = opacities.indexOf(Math.max(...opacities));
this.elements.forEach((element, index) => {
if (index === active) {
element.nativeElement.classList.remove('uk-disabled');
} else {
element.nativeElement.classList.add('uk-disabled');
}
})
}
})
});
this.elements.forEach(element => {
mutationObserver.observe(element.nativeElement, {attributes: true});
});
this.subscriptions.push(intersectionObserver);
this.subscriptions.push(mutationObserver);
}
private getPageContents() {
this.subscriptions.push(this.helper.getPageHelpContents(this.properties, 'monitor', this._router.url).subscribe(contents => {
this.pageContents = contents;
@ -162,14 +183,6 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
}));
}
public get stakeholdersNumber(): number {
if(this.type === null) {
return this.stakeholders.length;
} else {
return this.stakeholders.filter(stakeholder => stakeholder.type === this.type).length;
}
}
getNumbers() {
this.subscriptions.push(this._refineFieldResultsService.getRefineFieldsResultsByEntityName(["funder"], "project", this.properties).subscribe(
data => {
@ -181,7 +194,7 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
//console.log(err);
this.handleError("Error getting 'funder' field results of projects", err);
}));
this.subscriptions.push(this._searchResearchResultsService.numOfSearchResults("publication", "", this.properties).subscribe(
data => {
if (data && data > 0) {
@ -193,7 +206,7 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
this.handleError("Error getting number of publications", err);
}
));
this.subscriptions.push(this._searchResearchResultsService.numOfSearchResults("dataset", "", this.properties).subscribe(
data => {
if (data && data > 0) {
@ -205,7 +218,7 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
this.handleError("Error getting number of research data", err);
}
));
this.subscriptions.push(this._searchResearchResultsService.numOfSearchResults("software", "", this.properties).subscribe(
data => {
if (data && data > 0) {
@ -216,7 +229,7 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
this.handleError("Error getting number of software data", err);
}
));
this.subscriptions.push(this._searchResearchResultsService.numOfSearchResults("other", "", this.properties).subscribe(
data => {
if (data && data > 0) {
@ -270,10 +283,10 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
})
}
public slider(stakeholders: StakeholderInfo[], size: number = 6): StakeholderInfo[][] {
public slider(stakeholders: StakeholderInfo[], size: number = 6): StakeholderInfo[][] {
let slider: StakeholderInfo[][] = [];
for(let i = 0; i < (stakeholders.length/size); i++) {
slider.push(stakeholders.slice(i*size, ((i+1)*size)));
for (let i = 0; i < (stakeholders.length / size); i++) {
slider.push(stakeholders.slice(i * size, ((i + 1) * size)));
}
return slider;
}
@ -281,41 +294,33 @@ export class HomeComponent implements OnDestroy, AfterViewInit, IDeactivateCompo
get publicStakeholders(): StakeholderInfo[] {
return this.stakeholders.filter(stakeholder => stakeholder.visibility === "PUBLIC");
}
get privateStakeholders(): StakeholderInfo[] {
return this.stakeholders.filter(stakeholder => stakeholder.visibility !== "PUBLIC");
}
get funders(): StakeholderInfo[] {
if(this.stakeholders) {
return this.stakeholders.filter(stakeholder => stakeholder.type === "funder");
} else {
return [];
}
if (this.stakeholders) {
return this.stakeholders.filter(stakeholder => stakeholder.type === "funder");
} else {
return [];
}
}
get ris(): StakeholderInfo[] {
if(this.stakeholders) {
return this.stakeholders.filter(stakeholder => stakeholder.type === "ri");
} else {
return [];
}
get ris(): StakeholderInfo[] {
if (this.stakeholders) {
return this.stakeholders.filter(stakeholder => stakeholder.type === "ri");
} else {
return [];
}
}
get organizations(): StakeholderInfo[] {
if(this.stakeholders) {
return this.stakeholders.filter(stakeholder => stakeholder.type === "organization");
} else {
return [];
}
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
get organizations(): StakeholderInfo[] {
if (this.stakeholders) {
return this.stakeholders.filter(stakeholder => stakeholder.type === "organization");
} else {
return [];
}
}
private handleError(message: string, error): number {

@ -1 +1 @@
Subproject commit 4aabb739bff1e66301aa1e65a8046350fe8853ec
Subproject commit 58edff917732a45b75ad4175e2d647388d60c164