加载图像后 Knockout.js 中的容器元素淡入淡出

Fading in container elements in Knockout.js after image has loaded

我有一张图片和一些文本是由 Knockout.js 生成的。文本会立即显示,而图像需要更长的时间才能加载。

我想在容纳每个 image/text 对的容器上有一个 class,当图像完成加载然后切换 class 并拥有 image/text 对同时淡入。

我知道有一个 afterRender 回调,我很难编写被调用以定位元素并操纵 class 的函数。

http://jsfiddle.net/ClydeGrey/mfjv5j2c/4/

function SomeModel() {
  this.Firstname = ko.observable();
  this.Lastname = ko.observable();
  this.fadeIn = ko.observable();
}


function SomeViewModel() {
  var self = this;

  this.ArrayOfModels = ko.mapping.fromJS([]);
  this.dataArray = new Array;

  this.GetModelsByAjax = function() {
    $.ajax({
      type: 'POST',
      url: '/echo/json/',
      data: {
        json: JSON.stringify([{
            loaded: false,
            img: "https://source.unsplash.com/random",
            Firstname: "Bob",
            Lastname: "Smith"
          },
          {
            loaded: false,
            img: "https://source.unsplash.com/user/erondu",
            Firstname: "Ted",
            Lastname: "Smith"
          },

          {
            loaded: false,
            img: "https://source.unsplash.com/user/erondu/1600x900",
            Firstname: "Jim",
            Lastname: "Gump"
          }
        ]),
        delay: 0
      },
      context: this,
      success: function(data) {
        for (var x = 0; x < data.length; x++) {
          self.dataArray.push(data[x]);
        }
        /* self.dataArray.push(data); */
        console.log(self.dataArray);
        console.log(typeof(self.dataArray));
        console.log(data);
        console.log(typeof(data));
        self.SuccessfullyRetrievedModelsFromAjax(self.dataArray);
      },
      dataType: 'json'
    });
  };

  this.SuccessfullyRetrievedModelsFromAjax = function(models) {
    ko.mapping.fromJS(models, self.ArrayOfModels);
  };
}

ko.applyBindings(new SomeViewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://rawgit.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.debug.js"></script>
<button data-bind="click: GetModelsByAjax">Go</button>
<div data-bind="template: {name: 'model-template', foreach: ArrayOfModels}"></div>

<script id="model-template" type="text/html">
  <div data-bind="css: { fadeIn: loaded() === true }">
    <div data-bind="text: Firstname"></div>
    <div data-bind="text: Lastname"></div>
    <img width="100" height="100" data-bind="attr: { src: img }">
  </div>
</script>

您已经有一个 loaded 属性 初始化为 false 并且可观察。我们将以两种方式使用此 属性:

  1. css 绑定中,将 is-visible class 添加到我们可以设置样式的 img + 标签包装器
  2. event 绑定中,设置 <img> 标签触发 load 事件时的值。

您的新模板,没有任何其他更改:

<div class="Img" data-bind="css: { 'is-visible': loaded }">
    <div data-bind="text: Firstname"></div>
    <div data-bind="text: Lastname"></div>
    <img  width="100" height="100" 
          data-bind="attr: { src: img }, 
                     event: { load: loaded.bind($data, true) }">
</div>

淡入淡出的 css,您可以根据自己的喜好进行更改:

.Img {
  opacity: 0;
  transition: opacity 1s ease-in-out;
}

.Img.is-visible { opacity: 1; }

在您 fiddle 的更新版本中:http://jsfiddle.net/L7cn6y5r/