如果我有以下简单的 js/knockout 代码:
.js(视图模型):
var image = ko.observable('http://placehold.it/300x150');
看法:
<img data-bind={attr: {src: image}} />
如何创建一个 ko 绑定处理程序,该处理程序将在图像属性更改时执行简单的淡入淡出?
如果我有以下简单的 js/knockout 代码:
.js(视图模型):
var image = ko.observable('http://placehold.it/300x150');
看法:
<img data-bind={attr: {src: image}} />
如何创建一个 ko 绑定处理程序,该处理程序将在图像属性更改时执行简单的淡入淡出?
I think the best solution is to create another image and fade it in.
Here is a simple binding handler that will create a new image (or a div with a background image in this case) within the bound element every time the source observable is updated and fade to it with a CSS3 animation:
ko.bindingHandlers.transitionImage = {
init: function (element, valueAccessor) {
// create a holder for the images
var holder = document.createElement('div');
holder.style['position'] = 'relative';
holder.style['height'] = '100%';
holder.style['width'] = '100%';
element.appendChild(holder);
// create initial image
var url = ko.utils.unwrapObservable(valueAccessor());
var fore = document.createElement('div');
fore.style['background-image'] = 'url(' + url + ')';
fore.style['position'] = 'absolute';
fore.style['height'] = '100%';
fore.style['width'] = '100%';
fore.style['background-size'] = '100% 100%'
holder.appendChild(fore);
},
update: function (element, valueAccessor) {
var url = ko.utils.unwrapObservable(valueAccessor());
// retrieve the holder element
var holder = element.childNodes[0];
// create new image to transition to
var fore = document.createElement('div');
fore.className = 'transition';
fore.style['background-image'] = 'url(' + url + ')';
fore.style['position'] = 'absolute';
fore.style['height'] = '100%';
fore.style['width'] = '100%';
fore.style['background-size'] = '100% 100%'
fore.style['opacity'] = '0'; // ensure it is hidden
holder.appendChild(fore);
// CSS3 animate opacity
setTimeout(function () {
fore.style['opacity'] = '1';
}, 0);
// dispose of unnecessary hidden images eventually
setTimeout(function () {
var toRemove = holder.childNodes[0];
var removed = holder.removeChild(toRemove);
delete removed;
}, 10000);
}
};
It requires some css in place for the opacity to get animated:
div.transition {
-webkit-transition: opacity 0.5s linear;
-moz-transition: opacity 0.5s linear;
-o-transition: opacity 0.5s linear;
transition: opacity 0.5s linear;
}
To use, bind it to a div container:
<div data-bind="transitionImage: image" style="width: 100px; height: 100px"></div>
The advantage with this approach is that it is quite easy to substitute in more complex animations like sliding by just playing with the css.