【问题标题】:AngularJS switch css theme on user selectionAngularJS 在用户选择时切换 css 主题
【发布时间】:2014-10-23 11:54:53
【问题描述】:

我从 bootswatch 下载了主题,并试图让用户切换主题。切换主题后,所有引导 css 都会暂时消失,直到加载新主题。如何在加载 css 之前阻止更改,或者在加载新主题之前切换回默认主题?

index.ejs(在头部)

<link rel="stylesheet" href="/external/bootstrap/css/bootstrap_yeti.min.css"
      ng-if="myTheme == ''">
<link rel="stylesheet" ng-href="/external/bootstrap/css/bootstrap_{{myTheme}}.min.css"
      ng-if="myTheme != ''">

选择

<select class="form-control"
        id="theme"
        name="theme"
        ng-model="theme"
        ng-change="newTheme()">
  <option value="" disabled>Select Theme</option>
  <option ng-repeat="(key, val) in availableThemes" value="{{val}}">{{key}}</option>
</select>

索引控制器

$scope.myTheme = '';
$rootScope.$watch('myTheme', function(value) {
  if (value != undefined) {
    $scope.myTheme = value;
  }
});

选择控制器

$scope.availableThemes = {
  Cerulean: 'cerulean',
  Cosmo:    'cosmo',
  Yeti:     'yeti'
};
$scope.newTheme = function() {
  console.log($scope.theme);
  if ($scope.theme != undefined) {
    $rootScope.myTheme = $scope.theme;
  }
}

感谢任何帮助!谢谢

【问题讨论】:

  • 尝试使用其中一个异步加载库,如 requirejs 或 dominoes 等,并在其回调中更改 myTheme 变量

标签: javascript html css angularjs twitter-bootstrap


【解决方案1】:

我发现最好保持简单,并且不需要像其他人建议的那样预先加载所有主题。

使用 ng-href 坚持单个标签:

<link rel="stylesheet" ng-href="/external/bootstrap/css/bootstrap_{{myTheme}}.min.css">

并在索引控制器中将您范围内的 myVar 初始化为“yeti”:

$scope.myTheme = 'yeti';
$rootScope.$watch('myTheme', function(value) {
  if (value != undefined) {
    $scope.myTheme = value;
  }
});

其余的保持不变。

【讨论】:

  • 是否可以避免页面加载时暂时缺少主题?
  • @Josep Sayol 在角度方面的答案更好!
【解决方案2】:

我认为这不是 AngularJS 的问题。我认为你的方法应该不同。

据我所知,主题功能通常如下实现。

  1. 为每个主题(蔚蓝、宇宙、雪人)创建一个 CSS 文件。您应该编辑 CSS 文件以免相互冲突。 (把 .cerulean, .cosmo, .yeti 放在所有 CSS 选择器的前面。如果你使用 sass 或更少,会容易得多。)

  2. 从 HTML 头部加载所有 CSS 文件。

    <link rel="stylesheet" href="/bootstrap/css/bootstrap_cerulean.min.css">
    <link rel="stylesheet" href="/bootstrap/css/bootstrap_cosmo.min.css">
    <link rel="stylesheet" href="/bootstrap/css/bootstrap_yeti.min.css">
    
  3. 如果用户选择了主题,则将主体或根元素类更改为相应的主题名称。

    <body class="cerulean">
    <body class="cosmo">
    <body class="yeti">
    

【讨论】:

  • 我发现我还可以将 async 标记添加到第二个样式表链接,并且在加载时,将使用以前的样式表。但是,您的解决方案更好。如果第二个样式表缺少第一个样式表的任何内容,那么您将得到混合的 css 文件
  • 我不喜欢这个主意。我有同样的情况,我想使用 10 个主题,我不确定每个人都会使用它。告诉我为什么我的应用程序必须额外加载 1 兆字节?我认为有办法。
  • 这种方法让我的项目变得简单多了。谢谢!我忽略了一些如此明显的东西。
【解决方案3】:

试试这个方法吧..

<link href="css/style1.css" ng-if="load">
<link href="css/style2.css" ng-if="!load">

<body>
<input type="button" ng-click="changeTheme()" value="Change Theme"/>
</body>
<script>
$scope.load=true;
$scope.changeTheme=function(){
$scope.load=!$scope.load;
}
<script>

【讨论】:

  • 干得好兄弟!快速、简单、高效,我将重命名并添加几行。
【解决方案4】:

如果您在首次加载时包含所有主题,则它们都必须由浏览器加载。甚至不清楚用户是否会切换主题。那么为什么要加载所有这些。所以这里有几个选择。

1. Ng-if

尝试向ng-if 投放广告到link

<link ng-if="theme" ng-href="{{theme}}">

我不确定它是否有效,但我在某处读到它对某些人有效

2。可见性

我在 ipad 上打字,所以我很短。

用类似的东西创建css文件

Body .container {display:none}
Body .loader {display:block}

将所有内容放入容器类 div 中。创建兄弟 div 类加载器并将加载器动画放在那里。

首先在头部加载/链接这个文件。然后在每个主题中链接您的主题添加这些规则的取消。

Body .container {display:block}
Body .loader {display:none}

因此,在 css 重新加载的那一刻,您将拥有一个加载器动画。

【讨论】:

    猜你喜欢
    • 2014-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 2020-05-04
    • 2022-01-21
    • 2017-06-01
    • 1970-01-01
    相关资源
    最近更新 更多