简体   繁体   中英

Calling function triggered by event from an external JS file in angular component

I am trying to convert a webpage designed by JS, HTML, CSS into an angular project. I have included the JS file in index.html as given below

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Sample</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body class="">
<app-root></app-root>

<script type="text/javascript" src="assets/scripts/sample.js"></script>
</body>
</html>

sample.js

if (document.getElementById("fixedHeader")) {
    window.onscroll = function () { fixedHeader(); };
    var header = document.getElementById("fixedHeader");
    var fixed = header.offsetTop;
} 
function fixedHeader() {
    if (window.pageYOffset > fixed) {
        header.classList.add("fixed-active-lob");
        $('body').addClass("fixed-nav");
    } else {
        header.classList.remove("fixed-active-lob");
        $('body').removeClass("fixed-nav");
    }
}

current.component.html

<div class="gb-nav gn">
    <div id="fixedHeader" class="header">....
    </div>
</div>

sample.css File included in styles.css having

.gb-nav.gn .fixed-active-lob {
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 999999;
    -webkit-box-shadow: 0px 10px 15px -1px rgba(0,0,0,0.45);
    -moz-box-shadow: 0px 10px 15px -1px rgba(0,0,0,0.45);
    box-shadow: 0px 10px 15px -1px rgba(0,0,0,0.45);
}
body.fixed-nav{
    padding-top:56px
}

I was not able to trigger the function from sample.js in angular component. However I was able to reap the desired result by defining the same function again in the

current.component.ts as:

@HostListener('window:scroll', ['$event'])
    scrollHandler(event: any) {
    console.log("Scroll event", event);
    this.fixedHeader();
    }
fixedHeader() {
    var header = document.getElementById("fixedHeader");
    var fixed: number = 0;
    if (header?.offsetTop != undefined) {
      fixed = header?.offsetTop;
    } else {
      fixed = 0;
    }
    if (window.pageYOffset > fixed) {
        header?.classList.add("fixed-active-lob");
        $('body').addClass("fixed-nav");
    } else {
        header?.classList.remove("fixed-active-lob");
        $('body').removeClass("fixed-nav");
    }
}

But I would like to use the function from the JS file instead of redoing it in the ts file, please help.

First, sample.js export fixedHeader like so

if (document.getElementById("fixedHeader")) {
  window.onscroll = function () { fixedHeader(); };
  var header = document.getElementById("fixedHeader");
  var fixed = header.offsetTop;
}  

export function fixedHeader() {
  if (window.pageYOffset > fixed) {
    header.classList.add("fixed-active-lob");
    $('body').addClass("fixed-nav");
  } else {
    header.classList.remove("fixed-active-lob");
    $('body').removeClass("fixed-nav");
  }
} 

With this adjustment, we've made sample.js into a module, with a single export named fixedHeader , and have thus enabled other modules, such as our current.component.ts , to consume it via the standard, explicit, and canonical method for sharing code in JavaScript: Modules.

Next, set "allowJs": true in your project's tsconfig.json , to inform TypeScript that our project includes a mix of both TypeScript and JavaScript source files.

Finally, import the fixedHeader function we've exported from sample.js directly into current.component.ts , remove the now redundant method from the Angular component class, and call the imported function as follows

 import {Component, HostListener} from '@angular/core';

 import {fixedHeader} from '../assets/scripts/sample.js';

 @Component({
   // Angular boilerplate and ceremony
 })
 export class CurrentComponent { // or whatever it is actually called
   @HostListener('window:scroll', ['$event'])
   scrollHandler(event: Event) {
     console.log("Scroll event", event);
  
     fixedHeader();
  }
}

Finally, remove the script tag that originally loaded sample.js from index.html .

Note: adjust import path above as needed based on the actual location of the files relative to one another.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM