【问题标题】:Bullet colors don't display correctly in Chrome when changed by Angular由 Angular 更改时,项目符号颜色在 Chrome 中无法正确显示
【发布时间】:2017-02-21 08:04:06
【问题描述】:

谁能解释为什么这些项目符号会在 Firefox 和 IE 中正确改变颜色,但在 Chrome 中却不能(我当前的版本是 47.0.2526.106)?为什么第一个ul 中的子弹一直是白色的,而其他的一开始就变了?

请注意,无论是绑定到 class 还是使用 ng-class 属性,我都会得到相同的行为。

有没有办法让颜色正确更新?

火狐/IE:

铬:

angular.module('myApp', [])
  .controller('myCtrl', [
    '$scope',
    '$interval',
    function($scope, $interval) {
      var values = ['Hello', 'Oops', 'Uh-Oh...'];
      var classes = ['good', 'warning', 'danger'];
      var nItems = 8;
      $scope.items = [];

      for (var i = 0; i < nItems; i++) {
        $scope.items.push({});
      }

      function updateItems() {
        for (var i = 0; i < $scope.items.length; i++) {
          var item = $scope.items[i];
          var chosen = Math.floor(Math.random() * values.length);
          item.value = values[chosen];
          item.class = classes[chosen];
        }
      }

      $interval(updateItems, 3000);
    }
  ]);
body {
  background: #333;
  color: white;
}
ul {
  display: inline-block;
}
.good {
  color: limegreen;
}
.warning {
  color: yellow;
}
.danger {
  color: red;
}
<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-controller="myCtrl">
  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li ng-class="{'good': item.class==='good', 'warning': item.class==='warning', 'danger': item.class==='danger'}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

</body>

</html>

更新

大约一年后回到这个问题,谷歌似乎已经修复了导致这个问题的渲染错误,尽管我不确定哪个版本包含修复。我在 Chrome v56.0.2924.87 上不再看到此问题。

【问题讨论】:

  • 触发重绘事件似乎可以解决我在 Chrome 中的问题......虽然这是一个 hack-ish 解决方案。我不知道任何其他解决方法,因为这绝对是一个渲染问题。
  • 显然根本原因是 $interval 语句。用 $timeout 调用它并在 updateItems 结束时用另一个 $timeout 再次调用它会产生相同的间隔效果,但会得到正确的显示。不知道为什么。我很想听听这背后的技术。

标签: javascript html css angularjs google-chrome


【解决方案1】:

这是一个 Chrome 渲染错误。

一种选择是使用伪元素插入自定义项目符号。

ul {
  display: inline-block;
  list-style: none;
}
ul li:before {
  content: '\2022';
  text-indent: -1em;
  display: inline-block;
}

这是更新后的示例:

angular.module('myApp', [])
  .controller('myCtrl', [
    '$scope',
    '$interval',
    function($scope, $interval) {
      var values = ['Hello', 'Oops', 'Uh-Oh...'];
      var classes = ['good', 'warning', 'danger'];
      var nItems = 8;
      $scope.items = [];

      for (var i = 0; i < nItems; i++) {
        $scope.items.push({});
      }

      function updateItems() {
        for (var i = 0; i < $scope.items.length; i++) {
          var item = $scope.items[i];
          var chosen = Math.floor(Math.random() * values.length);
          item.value = values[chosen];
          item.class = classes[chosen];
        }
      }

      $scope.getItemValue = function(item) {
        return item.value;
      };

      $interval(updateItems, 3000);
    }
  ]);
body {
  background: #333;
  color: white;
}
ul {
  display: inline-block;
  list-style: none;
}
ul li:before {
  content: '\2022';
  text-indent: -1em;
  display: inline-block;
}
.good {
  color: limegreen;
}
.warning {
  color: yellow;
}
.danger {
  color: red;
}
<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-controller="myCtrl">
  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li ng-class="{'good': item.class==='good', 'warning': item.class==='warning', 'danger': item.class==='danger'}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

</body>

</html>

另一个选项是触发repaint event 以强制浏览器更新样式。这绝对是一个 hackish 选项,但它仍然有效:

function forceRepaint() {
  document.body.style.display = 'none';
  document.body.offsetHeight;
  document.body.style.display = '';
}

这是另一个更新的示例:

angular.module('myApp', [])
  .controller('myCtrl', [
    '$scope',
    '$interval',
    function($scope, $interval) {
      var values = ['Hello', 'Oops', 'Uh-Oh...'];
      var classes = ['good', 'warning', 'danger'];
      var nItems = 8;
      $scope.items = [];

      for (var i = 0; i < nItems; i++) {
        $scope.items.push({});
      }

      function updateItems() {
        for (var i = 0; i < $scope.items.length; i++) {
          var item = $scope.items[i];
          var chosen = Math.floor(Math.random() * values.length);
          item.value = values[chosen];
          item.class = classes[chosen];

          forceRepaint();
        }
      }

      $scope.getItemValue = function(item) {
        return item.value;
      };

      $interval(updateItems, 3000);
    }
  ]);


function forceRepaint() {
  document.body.style.display = 'none';
  document.body.offsetHeight;
  document.body.style.display = '';
}
body {
  background: #333;
  color: white;
}
ul {
  display: inline-block;
}
.good {
  color: limegreen;
}
.warning {
  color: yellow;
}
.danger {
  color: red;
}
<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-controller="myCtrl">
  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li ng-class="{'good': item.class==='good', 'warning': item.class==='warning', 'danger': item.class==='danger'}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

</body>

</html>

【讨论】:

  • 这是一个很好的解决方法。知道为什么会发生这种情况吗?
【解决方案2】:

一个 一位评论者说这似乎是渲染错误,但这里有一个解决方法,只需使用:before 自己为点着色。请参阅 css 部分(只是想让它保持可运行)

angular.module('myApp', [])
  .controller('myCtrl', [
    '$scope',
    '$interval',
    function($scope, $interval) {
      var values = ['Hello', 'Oops', 'Uh-Oh...'];
      var classes = ['good', 'warning', 'danger'];
      var nItems = 8;
      $scope.items = [];

      for (var i = 0; i < nItems; i++) {
        $scope.items.push({});
      }

      function updateItems() {
        for (var i = 0; i < $scope.items.length; i++) {
          var item = $scope.items[i];
          var chosen = Math.floor(Math.random() * values.length);
          item.value = values[chosen];
          item.class = classes[chosen];
        }
      }

      $scope.getItemValue = function(item) {
        return item.value;
      };

      $interval(updateItems, 3000);
    }
  ]);
body {
  background: #333;
  color: white;
}
.good {
  color: limegreen;
}
.warning {
  color: yellow;
}
.danger {
  color: red;
}

/* made the dots yourself */
ul {
  display: inline-block;
  list-style: none;
  padding:0;
  margin:0;
}

li { 
  padding-left: 1em; 
  text-indent: -.7em;
}

li.warning:before {
  content: "• ";
  color: yellow;
}

li.danger:before {
  content: "• ";
  color: red;
}

li.good:before {
  content: "• ";
  color: limegreen;
}
<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-controller="myCtrl">
  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li ng-class="{'good': item.class==='good', 'warning': item.class==='warning', 'danger': item.class==='danger'}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

</body>

</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-17
    • 2015-09-11
    相关资源
    最近更新 更多