加载图像后 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
并且可观察。我们将以两种方式使用此 属性:
- 在
css
绑定中,将 is-visible
class 添加到我们可以设置样式的 img + 标签包装器
- 在
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/
我有一张图片和一些文本是由 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
并且可观察。我们将以两种方式使用此 属性:
- 在
css
绑定中,将is-visible
class 添加到我们可以设置样式的 img + 标签包装器 - 在
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/