Conditionally-rendering css in html head

后端 未结 5 1938
忘了有多久
忘了有多久 2020-12-05 19:18

I am trying to dynamically add css to my html head using angular js. Here is sample code

5条回答
  •  感情败类
    2020-12-05 19:41

    There's a another option using $route.resolve and promises. This will wait until the CSS is actually loaded not only added to the head (after that the browser just starts retrieving the file and depending on CSS size can cause page reflow).

    // Routing setup
    .config(function ($routeProvider) {
      $routeProvider
      .when('/home', {
          controller: 'homeCtrl', 
          templateUrl: 'home.tpl.html'
      }).when('/users', {
          controller: 'usersCtrl', 
          controllerAs: 'vm',
          templateUrl: 'users.tpl.html',
          resolve: {
            load: ['injectCSS', function (injectCSS) {
              return injectCSS.set("users", "users.css");
            }]
          }
      }).otherwise({
          // default page
          redirectTo: '/home'
      });
    })
    

    Service implementation

    .factory("injectCSS", ['$q', '$http', 'MeasurementsService', function($q, $http, MeasurementsService){
      var injectCSS = {};
    
      var createLink = function(id, url) {
        var link = document.createElement('link');
        link.id = id;
        link.rel = "stylesheet";
        link.type = "text/css";
        link.href = url;
        return link;
      }
    
      var checkLoaded = function (url, deferred, tries) {
        for (var i in document.styleSheets) {
          var href = document.styleSheets[i].href || "";
          if (href.split("/").slice(-1).join() === url) {
            deferred.resolve();
            return;
          }
        }
        tries++;
        setTimeout(function(){checkLoaded(url, deferred, tries);}, 50); 
      };
    
      injectCSS.set = function(id, url){
        var tries = 0,
          deferred = $q.defer(),
          link;
    
        if(!angular.element('link#' + id).length) {
          link = createLink(id, url);
          link.onload = deferred.resolve;
          angular.element('head').append(link);
        }
        checkLoaded(url, deferred, tries);
    
        return deferred.promise;
      };
    
      return injectCSS;
    }])
    

    You could add a timeout using tries if this is something you would like to include.

    Check out this post for more details:https://medium.com/angularjs-meetup-south-london/angular-dynamically-injecting-css-file-using-route-resolve-and-promises-7bfcb8ccd05b

提交回复
热议问题