如何使用angular-cli创建加载屏幕

时间:2017-04-03 18:13:06

标签: angular webpack angular-cli loader

我有一个用angular-cli创建的angular2项目。 Angular-cli使用webpack。

我会定制装载机,因为"正在加载......"在白色背景上的黑色对我来说不合适。

所以,我用加载器的svg动画重写了index.html。但动画滞后,有时冻结。我的第一个解决方案,删除index.html末尾的* .bundle.js。然后,我捕获DOMContentLoaded事件以显示svg。宾果,非常整洁。

然后,我为webpack添加动态不同的脚本* .bundle.js。

问题出在main.bundle.js中,因为执行期间出错。

如果我让DOM中的原始脚本工作但不是动态的。

所以,而不是:

  <script type="text/javascript" src="inline.bundle.js"></script>
  <script type="text/javascript" src="polyfills.bundle.js"></script>
  <script type="text/javascript" src="scripts.bundle.js"></script>
  <script type="text/javascript" src="styles.bundle.js"></script>
  <script type="text/javascript" src="vendor.bundle.js"></script>
  <script type="text/javascript" src="main.bundle.js"></script>

我说:

 <script type="text/javascript">
    var body = document.getElementsByTagName("body")[0];
    var app = document.getElementsByTagName("app-root")[0];
    body.removeChild(app);

    function appendScript(src){
      var s = document.createElement("script");
      s.src = src;
      s.type = "text/javascript";
      body.appendChild(s);
    }
    document.addEventListener("DOMContentLoaded", function(){
      var timer = setInterval(function(){
        body.appendChild(app);

        appendScript("inline.bundle.js");
        appendScript("polyfills.bundle.js");
        appendScript("scripts.bundle.js");
        appendScript("styles.bundle.js");
        appendScript("vendor.bundle.js");
        appendScript("main.bundle.js");
        clearInterval(timer);
      }, 1500);
    })
  </script>

我想在加载不同的包之前显示加载器..

我删除了app-root,因为我希望不透明度上的css动画具有淡入淡出效果

错误是:

Uncaught TypeError: Cannot read property 'call' of undefined
    at __webpack_require__ (bootstrap c9cc4a4…:52)
    at Object.192 (src async:7)
    at __webpack_require__ (bootstrap c9cc4a4…:52)
    at Object.635 (main.bundle.js:4838)
    at __webpack_require__ (bootstrap c9cc4a4…:52)
    at webpackJsonpCallback (bootstrap c9cc4a4…:23)
    at main.bundle.js:1

我在__webpack__require函数中添加了一个console.log来显示打破执行的moduleId。这个moduleId是1

你有什么想法吗?

3 个答案:

答案 0 :(得分:0)

有两种可能的解决方案: 如果你想拥有静态动画,只需将此动画放入index.html即可 在app标签内

<app-root>
    <div id="preloader">
      <div class="sk-wave">
          <div class="sk-rect sk-rect1"></div>
          <div class="sk-rect sk-rect2"></div>
          <div class="sk-rect sk-rect3"></div>
          <div class="sk-rect sk-rect4"></div>
          <div class="sk-rect sk-rect5"></div>
      </div>
  </div>
</app-root>

我有css样式为preloader元素制作动画,但这不相关。重要的是,在应用程序加载app-root元素的所有内容后,应用程序将覆盖此加载器。

=============================================== ======================== 第二个选项......这次你不要把它放在app-root元素中。

<body>
  <app-root></app-root>
  <div id="preloader">
      <div class="sk-wave">
          <div class="sk-rect sk-rect1"></div>
          <div class="sk-rect sk-rect2"></div>
          <div class="sk-rect sk-rect3"></div>
          <div class="sk-rect sk-rect4"></div>
          <div class="sk-rect sk-rect5"></div>
      </div>
  </div>
</body

然后使用Angular2 Lifecicle hooks隐藏视图后的预加载器

import { Component, AfterViewInit } from '@angular/core';
import { PreloaderService } from './_ui-module/_preloader';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: [ './app.component.styl' ]
})
export class AppComponent implements AfterViewInit {

    constructor(private preloader: PreloaderService){

    }

    //HERE
    ngAfterViewInit(): void {
        this.preloader.hide();
    }

}

答案 1 :(得分:0)

找到纯css加载页面并将<div>元素放在app-root内。这些都是lukehaas真的很酷:https://projects.lukehaas.me/css-loaders/

这是我使用上述链接中的一个微调器执行的工作示例:https://plnkr.co/edit/J3JNhm82Rgxq1h9h9ktb?p=preview

以下是我所做的更改:

  1. body内我添加了<style>代码,从源代码复制了上面链接中的一个样式,并将其添加到<style>
  2. 再次从lukehaas网站的来源添加源html。将其添加到根元素my-app中,如下所示:(在您的情况下为<app-root>)。

    <my-app>
          <div class="loader">Loading...</div>
    </my-app>
    
  3. 一旦角度已经自举,它将移除内部的一切,装载机将消失。

答案 2 :(得分:0)

我找到了解决方案。而且非常有效

我修复了我的appendScript功能。

function appendScript(src){
  var s = document.createElement("script");
  s.src = src;
  s.type = "text/javascript";
  s.async = false;
  body.appendChild(s);
}

请参阅:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script

“[1]在不支持async属性的旧浏览器中,插入解析器的脚本会阻塞解析器;脚本插入的脚本在IE和WebKit中异步执行,但在Opera和4.0之前的Firefox中同步执行。在Firefox中4.0,对于脚本创建的脚本,async DOM属性默认为true,因此默认行为与IE和WebKit的行为相匹配。要求脚本插入的外部脚本在document.createElement(“script”的浏览器中按插入顺序执行“).async评估为true(例如Firefox 4.0),在要维护顺序的脚本上设置.async = false。永远不要从异步脚本调用document.write()。在Gecko 1.9.2中,调用document.write ()具有不可预测的效果。在Gecko 2.0中,从异步脚本调用document.write()无效(除了向错误控制台打印警告)。

[2]从Gecko 2.0(Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)开始,将通过调用document.createElement(“script”)创建的脚本元素插入DOM不再强制按插入顺序执行。此更改使Gecko能够正确遵守HTML5规范。要使插入脚本的外部脚本按其插入顺序执行,请在它们上设置.async = false。“