Overlay with spinner

前端 未结 6 1204
忘了有多久
忘了有多久 2021-01-30 16:15

I\'m trying to create an overlay that overlays a page with a spinner in the middle. What\'s the simplest way to accomplish this? I only need to worry about IE 8 and above.

相关标签:
6条回答
  • 2021-01-30 16:54

    use a css3 class "spinner". It's more beautiful and you don't need .gif

    enter image description here

    .spinner {
       position: absolute;
       left: 50%;
       top: 50%;
       height:60px;
       width:60px;
       margin:0px auto;
       -webkit-animation: rotation .6s infinite linear;
       -moz-animation: rotation .6s infinite linear;
       -o-animation: rotation .6s infinite linear;
       animation: rotation .6s infinite linear;
       border-left:6px solid rgba(0,174,239,.15);
       border-right:6px solid rgba(0,174,239,.15);
       border-bottom:6px solid rgba(0,174,239,.15);
       border-top:6px solid rgba(0,174,239,.8);
       border-radius:100%;
    }
    
    @-webkit-keyframes rotation {
       from {-webkit-transform: rotate(0deg);}
       to {-webkit-transform: rotate(359deg);}
    }
    @-moz-keyframes rotation {
       from {-moz-transform: rotate(0deg);}
       to {-moz-transform: rotate(359deg);}
    }
    @-o-keyframes rotation {
       from {-o-transform: rotate(0deg);}
       to {-o-transform: rotate(359deg);}
    }
    @keyframes rotation {
       from {transform: rotate(0deg);}
       to {transform: rotate(359deg);}
    }
    

    Exemple of what is looks like : http://jsbin.com/roqakuxebo/1/edit

    You can find a lot of css spinners like this here : http://cssload.net/en/spinners/

    0 讨论(0)
  • 2021-01-30 17:00
    #overlay {
        position: fixed;
        width: 100%;
        height: 100%;
        background: black url(spinner.gif) center center no-repeat;
        opacity: .5;
    }
    

    it's better to use rgba color instead of opacity to prevent applying alpha to spinner image.

    background: rgba(0,0,0,.5) url(spinner.gif) center center no-repeat;
    
    0 讨论(0)
  • 2021-01-30 17:00

    As an update, for Angular 7, a very good example, loading plus http interceptor, here: https://nezhar.com/blog/create-a-loading-screen-for-angular-apps/.

    For version 6, you need a small adjustment when you use Subject. You need to add the generic type.

    loadingStatus: Subject<boolean> = new Subject();
    

    I'm using angular material, so instead of a loading text, you can use mat-spinner.

    <mat-spinner></mat-spinner>
    

    Update: the code from the previous page will not complete work (regarding the interceptor part), but here you have the complete solution: https://github.com/nezhar/snypy-frontend

    And as Miranda recommended into comments, here is also the solution:

    The loading screen component:

    loading-screen.component.ts

        import { Component, ElementRef, ChangeDetectorRef, OnDestroy, AfterViewInit } from '@angular/core';
    import { Subscription } from 'rxjs';
    import { LoadingScreenService } from '../services/loading-screen.service';
    
    @Component({
      selector: 'app-loading-screen',
      templateUrl: './loading-screen.component.html',
      styleUrls: ['./loading-screen.component.css']
    })
    export class LoadingScreenComponent implements AfterViewInit, OnDestroy {
    
      loading: boolean = false;
      loadingSubscription: Subscription;
    
      constructor(
        private loadingScreenService: LoadingScreenService,
        private _elmRef: ElementRef,
        private _changeDetectorRef: ChangeDetectorRef
      ) { }
    
      ngAfterViewInit(): void {
        this._elmRef.nativeElement.style.display = 'none';
        this.loadingSubscription = this.loadingScreenService.loadingStatus.pipe().subscribe(
          (status: boolean) => {
            this._elmRef.nativeElement.style.display = status ? 'block' : 'none';
            this._changeDetectorRef.detectChanges();
          }
        );
      }
    
      ngOnDestroy() {
        console.log("inside destroy loading component");
        this.loadingSubscription.unsubscribe();
      }
    
    }
    

    loading-screen.component.html

    <div id="overlay">
      <mat-spinner class="content"></mat-spinner>
    </div>
    

    loading-screen.component.css

      #overlay {
          position: fixed; /* Sit on top of the page content */
          display: block; /* Hidden by default */
          width: 100%; /* Full width (cover the whole page) */
          height: 100%; /* Full height (cover the whole page) */
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          background-color: rgba(60, 138, 255, 0.1); /* Black background with opacity */
          opacity: 0.5;
          z-index: 2; /* Specify a stack order in case you're using a different order for other elements */
          cursor: progress; /* Add a pointer on hover */
      }
    
      .content {
          position: absolute;
          top: 50%;
          left: 50%;
          font-size: 50px;
          color: white;
          transform: translate(-50%, -50%);
          -ms-transform: translate(-50%, -50%);
      }
    

    Don't forget to add the component to your root component. In my case, AppComponent

    app.component.html

    <app-loading-screen></app-loading-screen>
    

    The service that will manage the component: loading-screen.service.ts

    import { Injectable } from '@angular/core';
    import { Subject } from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class LoadingScreenService {
    
      constructor() { }
    
      private _loading: boolean = false;
      loadingStatus: Subject<boolean> = new Subject();
    
      get loading(): boolean {
        console.log("get loading: " + this._loading);
        return this._loading;
      }
    
      set loading(value) {
        console.log("get loading: " + value);
        this._loading = value;
        this.loadingStatus.next(value);
      }
    
      startLoading() {
        console.log("startLoading");
        this.loading = true;
      }
    
      stopLoading() {
        console.log("stopLoading");
        this.loading = false;
      }
    }
    

    Here is the http interceptor, which will show/hide the component, using the previous service.

    loading-screen-interceptor.ts

    import { Injectable } from '@angular/core';
    import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
    import { LoadingScreenService } from '../services/loading-screen.service';
    import { Observable } from 'rxjs';
    import { finalize } from 'rxjs/operators';
    
    @Injectable()
    export class LoadingScreenInterceptor implements HttpInterceptor {
    
        activeRequests: number = 0;
    
        constructor(
            private loadingScreenService: LoadingScreenService
        ) { }
    
        intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
            console.log("inside interceptor");
    
            if (this.activeRequests === 0) {
                this.loadingScreenService.startLoading();
            }
    
            this.activeRequests++;
    
            return next.handle(request).pipe(
                finalize(() => {
                    this.activeRequests--;
                    if (this.activeRequests === 0) {
                        this.loadingScreenService.stopLoading();
                    }
                })
            )
        };
    }
    

    And in your app.module.ts, don't forget to config the interceptor

    providers: [
        {
          provide: HTTP_INTERCEPTORS,
          useClass: LoadingScreenInterceptor,
          multi: true
        }
      ]
    
    0 讨论(0)
  • 2021-01-30 17:02

    Here is an Pure CSS endless spinner. Position absolute, to place the buttons on top of each other.

    button {
                position: absolute;
                width: 150px;
                font-size: 120%;
                padding: 5px;
                background: #B52519;
                color: #EAEAEA;
                border: none;
                margin: 50px;
                border-radius: 5px;
                display: flex;
                align-content: center;
                justify-content: center;
                transition: all 0.5s;
                cursor: pointer;
            }
    
            #orderButton:hover {
                color: #c8c8c8;
            }
    
            #orderLoading {
                animation: rotation 1s infinite linear;
                height: 20px;
                width: 20px;
                display: flex;
                justify-content: center;
                align-items: center;
                border-radius: 100%;
                border: 2px solid;
                border-style: outset;
                color: #fff;
            }
    
            @keyframes rotation {
                from {
                    transform: rotate(0deg);
                }
                to {
                    transform: rotate(360deg);
                }
            }
    <button><div id="orderLoading"></div></button>
    <button id="orderButton" onclick="this.style.visibility= 'hidden';">Order!</button>

    0 讨论(0)
  • 2021-01-30 17:03

    And for a spinner like iOs I use this:

    enter image description here

    html:

      <div class='spinner'>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
      </div>
    

    Css:

    .spinner {
      font-size: 30px;
      position: relative;
      display: inline-block;
      width: 1em;
      height: 1em;
    }
    
    .spinner div {
      position: absolute;
      left: 0.4629em;
      bottom: 0;
      width: 0.074em;
      height: 0.2777em;
      border-radius: 0.5em;
      background-color: transparent;
      -webkit-transform-origin: center -0.2222em;
          -ms-transform-origin: center -0.2222em;
              transform-origin: center -0.2222em;
      -webkit-animation: spinner-fade 1s infinite linear;
              animation: spinner-fade 1s infinite linear;
    }
    .spinner div:nth-child(1) {
      -webkit-animation-delay: 0s;
              animation-delay: 0s;
      -webkit-transform: rotate(0deg);
          -ms-transform: rotate(0deg);
              transform: rotate(0deg);
    }
    .spinner div:nth-child(2) {
      -webkit-animation-delay: 0.083s;
              animation-delay: 0.083s;
      -webkit-transform: rotate(30deg);
          -ms-transform: rotate(30deg);
              transform: rotate(30deg);
    }
    .spinner div:nth-child(3) {
      -webkit-animation-delay: 0.166s;
              animation-delay: 0.166s;
      -webkit-transform: rotate(60deg);
          -ms-transform: rotate(60deg);
              transform: rotate(60deg);
    }
    .spinner div:nth-child(4) {
      -webkit-animation-delay: 0.249s;
              animation-delay: 0.249s;
      -webkit-transform: rotate(90deg);
          -ms-transform: rotate(90deg);
              transform: rotate(90deg);
    }
    .spinner div:nth-child(5) {
      -webkit-animation-delay: 0.332s;
              animation-delay: 0.332s;
      -webkit-transform: rotate(120deg);
          -ms-transform: rotate(120deg);
              transform: rotate(120deg);
    }
    .spinner div:nth-child(6) {
      -webkit-animation-delay: 0.415s;
              animation-delay: 0.415s;
      -webkit-transform: rotate(150deg);
          -ms-transform: rotate(150deg);
              transform: rotate(150deg);
    }
    .spinner div:nth-child(7) {
      -webkit-animation-delay: 0.498s;
              animation-delay: 0.498s;
      -webkit-transform: rotate(180deg);
          -ms-transform: rotate(180deg);
              transform: rotate(180deg);
    }
    .spinner div:nth-child(8) {
      -webkit-animation-delay: 0.581s;
              animation-delay: 0.581s;
      -webkit-transform: rotate(210deg);
          -ms-transform: rotate(210deg);
              transform: rotate(210deg);
    }
    .spinner div:nth-child(9) {
      -webkit-animation-delay: 0.664s;
              animation-delay: 0.664s;
      -webkit-transform: rotate(240deg);
          -ms-transform: rotate(240deg);
              transform: rotate(240deg);
    }
    .spinner div:nth-child(10) {
      -webkit-animation-delay: 0.747s;
              animation-delay: 0.747s;
      -webkit-transform: rotate(270deg);
          -ms-transform: rotate(270deg);
              transform: rotate(270deg);
    }
    .spinner div:nth-child(11) {
      -webkit-animation-delay: 0.83s;
              animation-delay: 0.83s;
      -webkit-transform: rotate(300deg);
          -ms-transform: rotate(300deg);
              transform: rotate(300deg);
    }
    .spinner div:nth-child(12) {
      -webkit-animation-delay: 0.913s;
              animation-delay: 0.913s;
      -webkit-transform: rotate(330deg);
          -ms-transform: rotate(330deg);
              transform: rotate(330deg);
    }
    
    @-webkit-keyframes spinner-fade {
      0% {
        background-color: #69717d;
      }
      100% {
        background-color: transparent;
      }
    }
    
    @keyframes spinner-fade {
      0% {
        background-color: #69717d;
      }
      100% {
        background-color: transparent;
      }
    }
    

    get from this website : https://365webresources.com/10-best-pure-css-loading-spinners-front-end-developers/

    0 讨论(0)
  • 2021-01-30 17:14

    Here is simple overlay div without using any gif, This can be applied over another div.

    <style>
    .loader {
      position: relative;
      border: 16px solid #f3f3f3;
      border-radius: 50%;
      border-top: 16px solid #3498db;
      width: 70px;
      height: 70px;
      left:50%;
      top:50%;
      -webkit-animation: spin 2s linear infinite; /* Safari */
      animation: spin 2s linear infinite;
    }
    #overlay{
        position: absolute;
        top:0px;
        left:0px;
        width: 100%;
        height: 100%;
        background: black;
        opacity: .5;
    }
    .container{
        position:relative;
        height: 300px;
        width: 200px;
        border:1px solid
    }
    
    /* Safari */
    @-webkit-keyframes spin {
      0% { -webkit-transform: rotate(0deg); }
      100% { -webkit-transform: rotate(360deg); }
    }
    
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
    </style>
    
    <h2>How To Create A Loader</h2>
    
    <div class="container">
      <h3>Overlay over this div</h3>
      <div id="overlay">
          <div class="loader"></div>
      </div>
    <div>
    
    0 讨论(0)
提交回复
热议问题