html head 中的条件渲染 css

Posted

技术标签:

【中文标题】html head 中的条件渲染 css【英文标题】:Conditionally-rendering css in html head 【发布时间】:2012-08-08 09:14:51 【问题描述】:

我正在尝试使用 Angular js 将 css 动态添加到我的 html 头部。这是示例代码

<div ng-repeat="stylesheet in stylesheets">
        <link href="/myapp/stylesheet.href" type="stylesheet.type" rel="stylesheet" media="stylesheet.media" title="stylesheet.title" />
</div>

此代码按预期工作,但是当浏览器加载页面时,它会尝试使用原始 angularjs 模板获取 css 资源,并且我在 firebug 的网络选项卡中看到“404 not found error”。

Eg: request http://localhost:8080/myapp/%7B%7Bstylesheet.href%7D%7D, status 404

当页面完全加载时,它会替换模板值并加载正确的 css。

有没有办法避免 404 错误并使其在 angularjs 处理后加载 css?

【问题讨论】:

【参考方案1】:

你应该使用ng-href而不是href。

<link ng-repeat="stylesheet in stylesheets" ng-href="stylesheet.href" type="stylesheet.type" rel="stylesheet" />

Example

【讨论】:

【参考方案2】:

我创建了一个 AngularJS 服务,以便轻松使用 @Artem 解决方案。

It's here on GitHub.

【讨论】:

太棒了,我希望 Angular 社区能够分享和积累与 jquery 插件相同的伟大生态系统- 这很酷!我喜欢你的服务。它非常易于使用,并且 singlePageMode 效果很好!谢谢【参考方案3】:

还有一个使用 $route.resolve 和 promises 的选项。这将等到 CSS 实际加载后才添加到头部(之后浏览器才开始检索文件,并且根据 CSS 大小可能会导致页面重排)。

// 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'
  );
)

服务实现

.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;
])

如果您想包含这些内容,您可以使用尝试添加超时。

查看这篇文章了解更多详情:https://medium.com/angularjs-meetup-south-london/angular-dynamically-injecting-css-file-using-route-resolve-and-promises-7bfcb8ccd05b

【讨论】:

【参考方案4】:

我创建了一个非常简单的示例,说明如何进行有条件的 CSS 添加

<link rel="stylesheet" ng-if="lang_direction == 'rtl'" ng-href="lang_direction == 'rtl' ? 'css/rtl.css' : ''" >

【讨论】:

【参考方案5】:

对于任何希望在运行时使用 AngularJS 创建真正动态的 CSS 的人,这是我使用的。

index.html

<head> <style type="text/css" ng-bind-html="styles"></style> </head>

cssService

this.$rootScope.myStyles = ".test color : red; ";

这只是一个例子,如果你有一个 indexController 并把它放在$rootScope 之外,你最好把它放在一个 indexController 中

【讨论】:

以上是关于html head 中的条件渲染 css的主要内容,如果未能解决你的问题,请参考以下文章

Css 过渡不适用于 React 中的条件渲染

浏览器渲染

Vue中的条件渲染和循列表渲染

Vue.js 系列 - Vue 中的条件渲染

样式化组件中的条件渲染

如何有条件地渲染我的 CSS 类的一部分