【问题标题】:Angular - menu doesn't work on IE and FirefoxAngular - 菜单在 IE 和 Firefox 上不起作用
【发布时间】:2018-10-12 00:15:35
【问题描述】:

我正在使用 Javascript 菜单,它在我的 Angular 应用程序上加载 onInit,它在 Chrome 上运行良好,但在 IE Edge 和 Firefox 上运行良好。

我的打字稿文件上的代码是:

ngOnInit() {
   //getmenu items
$(document).ready(function() {
  //addclasses to menu, etc.. 
});

因此,在调试之后,我认为我找到了解决方案,即添加事件侦听器而不是 document.ready。

如果我添加事件监听器,现在事情就会变得混乱:

ngOnInit() {
//getmenu items
window.addEventListener('load', function () {
//addclasses to menu, etc.. 
});

当我第一次加载应用程序(登录页面 -> 重定向菜单页面所在的位置)时,它不起作用,但如果我按 f5 并在没有登录的情况下重新加载页面,它可以工作,仅在 firefox .. 在 IE 上不起作用不工作。但如果我改变:

 window.addEventListener('load', function () 

 window.addEventListener('focus', function () 

它在 firefox 和 chrome 上不起作用(子菜单闪烁)但在 IE 上起作用,在刷新页面后,正如我第一次所说的那样。

那么,问题是,是否有任何类型的事件监听器适用于每个浏览器?还是每次登录都必须刷新页面?我知道这个问题有点令人困惑。有谁知道如何解决这个问题?

【问题讨论】:

  • 你检查了你的pollyfills.ts吗?每样东西都正确导入??
  • 我导入了 core-js/es6/*(集合、地图、日期、符号等)、core-js/es6/reflect、core-js/es7/reflect 和 zone .js/dist/zone

标签: javascript angular addeventlistener


【解决方案1】:

addEventListener 适用于大多数浏览器 - 请参阅 https://caniuse.com/#feat=addeventlistener

这可能是因为你开得太早了试试这个:

ngAfterViewInit() {
  window.addEventListener('load', function () {
    //addclasses to menu, etc.. 
  });
}

编辑:

如果您想更多地延迟执行,请继续我们在 cmets 中的讨论:

ngAfterViewInit() {
  const interval = setInterval(() => {

    const condition = window.addEventListener
    if (condition) {
      // fire any code you want to when condition is met
      window.addEventListener('load', function () {
        //addclasses to menu, etc.. 
      });
      clearInterval(interval) // stop firing the code
    }
  }, 100) // fire the code every 100ms
}

不确定你想要实现什么,你的条件是什么,或者当条件满足时你想执行什么代码,但是如果你知道条件是什么,这种延迟代码执行的模式很容易遵循。

【讨论】:

  • 更改为 ngAfterViewInit,问题仍然存在,但现在我在任何浏览器上按 f5 或 crtl+f5 菜单开始工作.. 你是对的,因为我很早就加载了 js..但我怎么能推迟呢?
  • 您可以延迟 JS 的执行,但将 JS 包装在 setInterval 中,这将一直触发直到满足某些条件。我将在这篇文章中添加一个示例。
  • 我尝试了 3 秒的 setInterval 并执行 JS 代码,问题仍然存在。我不知道为什么或会发生什么。如果我将页面重新加载到 ip:port/ 或 url/ 它适用于每个浏览器,就像菜单仅在将页面重新加载到原始 url 后才有效。如果你愿意,我可以发布我的 TS 代码。。
【解决方案2】:

我知道 hagner,我一直在使用 onInit,并且工作正常,在这种情况下,我认为我会在 init 上提前触发 JS 函数。 让我这样说吧:

当我登录时,我进入仪表板,这意味着; ip:端口/仪表板 现在我给你这个:如果我将页面重新加载到 ip:port/,它适用于每个浏览器 为什么??

(如果我按 f5(ip:port/dashboard),则在 IE 上不起作用,只有当我重新加载到 ip:port/时才能使用

这是我的tipescript代码:它包含所有推送和生成菜单的代码,以及菜单的点击、子菜单以及是否在内部或外部点击等。

menu.compontent.ts:

export class MenuComponent implements OnInit {
    private sub: any;
    public menu;
    public arr;
    showMenu = '';

  constructor(private _menu: MenuService,
              private router: Router) {}
ngOnInit() {

      let times = 0;
      if( times === 0)
      {
this._menu.getMenu()
          .subscribe( res => {
              let data = res;

              console.log(data);
              this.arr = data;
              this.arr = (<any>Object).values(data);
              console.log(this.arr );
              //debugger;
              times ++; //only push json wich contains menu one time!!
          });
       }
window.addEventListener('load', function () {
"use strict";

          $('.menu > ul > li:has(ul)').addClass('menu-dropdown-icon');
          //Checks if li has sub (ul) and adds class for toggle icon - just an UI

          $('.menu > ul > li > ul:not(:has(ul))').addClass('normal-sub');
          //Checks if drodown menu's li elements have anothere level (ul), if not the dropdown is shown as regular dropdown, not a mega menu (thanks Luka Kladaric)

          $(".menu > nav > div > a").before("<a href=\"#\" class=\"menu-mobile\"><i class='icon-mod-mais fs1'></i></a>");
$(".menu > ul > li").click(function(e) {
              if ($(window).width() > 943) {
                  if ($(this).children('.menu-list').is(":visible")){
                      $(this).children('.menu-list').fadeToggle(15);
                      $(this).children('.menu-list').toggleClass('center');
                      e.preventDefault();
                  } else {
                      $('.menu-list').hide();
                      $('.menu-list').removeClass('center');
                      $(this).children('.menu-list').fadeToggle(15);
                      $(this).children('.menu-list').toggleClass('center');
                      e.preventDefault();
                  }
              }
          });

          $("body").click(function(e) {
              var target = e.target.className;
              if (target.indexOf("menu-button") == -1  ) {
                  $('.menu-list').hide();
                  $('.menu-list').removeClass('center');
                  return;
              }
          });
$(".menu > ul > li").click(function() {
              if ($(window).width() <= 943) {
                  $(this).children("ul").fadeToggle(100);
              }
          });
          //If width is less or equal to 943px dropdowns are displayed on click (thanks Aman Jain from stackoverflow)

          $(".menu-mobile").click(function(e) {
              $(".menu > ul").toggleClass('show-on-mobile');
              e.preventDefault();
          });
//If menu a clicked stay active
          $(".menu > ul > li > a").click(function() {
 if($( this ).hasClass( "active" )) {
                  $(this).removeClass("active");
              }else {
                  $(".menu > ul > li > a").removeClass("active");
                  $(this).addClass("active");
              }
          });
      });
  }
}

【讨论】:

    【解决方案3】:

    您已经在使用 OnInit 生命周期挂钩。当组件被创建/更新/销毁时,Angular 会调用不同的生命周期钩子,并允许您对事件采取行动。 Angular 框架确保这些事件在所有主流浏览器中都有效。对于您的用例,您不需要在 ngOnInit 方法中使用任何单独的事件侦听器,您可以使用 ngOnInit 或 ngAfterViewInit 方法来完成创建组件时所需的所有工作。有关更多信息,您可以阅读有关 Angular 生命周期钩子 here 的信息。

    【讨论】:

      猜你喜欢
      • 2017-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-04
      • 2014-02-28
      • 1970-01-01
      相关资源
      最近更新 更多