Skip to content

Instantly share code, notes, and snippets.

@sukobuto
Created February 11, 2014 06:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sukobuto/8930371 to your computer and use it in GitHub Desktop.
Save sukobuto/8930371 to your computer and use it in GitHub Desktop.
サンプルに惑わされるな!KnockoutでUIエフェクトを使う際のベター・プラクティス ref: http://qiita.com/sukobuto/items/9fc4bdc3463f13bdc00c
// jQuery の fadeIn() / fadeout() メソッドを使ってエレメントの 可視/不可視 を切り替える
ko.bindingHandlers.fadeVisible = {
init: function(element, valueAccessor) {
var value = valueAccessor();
$(element).toggle(ko.unwrap(value));
},
update: function(element, valueAccessor) {
var value = valueAccessor();
ko.unwrap(value) ? $(element).fadeIn() : $(element).fadeOut();
}
};
ko.bindingHandlers['class'] = {
update: function(element, valueAccessor) {
ko.bindingHandlers.css.update(element, valueAccessor);
if (jQuery) { // jQuery がロードされてたら、classChanged イベントを発火
jQuery(element).trigger('classChanged', [ valueAccessor() ]);
}
}
}
<ul data-bind="foreach: {
data: items,
afterAdd: effects.list.fadeIn,
beforeRemove: effects.list.fadeOut }">
<li data-bind="text: $data"></li>
</ul>
.message { /* 通常は透明 & 非表示 */
opacity: 0;
transition: opacity .3s
}
.message.shown { /* shown クラスがつくとフェードイン */
opacity: 1;
}
/* 簡略化のためにベンダープレフィックスは記載していません */
<ul data-bind="foreach: { data: items, afterAdd: showItem, beforeRemove: hideItem }">
<li data-bind="text: $data"></li>
</ul>
<p class="message" data-bind="class: { shown: displayMessage }">
尚、このメッセージは displayMessage プロパティが false になると自動的に消滅する。
</p>
// 古い IE へのポリフィルコード。
// <!--[if lt IE 9]> <![endif]--> 等を使って処理するとよい
$(function() {
$('.message').on('classChanged', function(e, data) {
if (ko.unwrap(data.shown)) {
$(this).fadeIn(300);
} else {
$(this).fadeOut(300);
}
};
});
function ViewModel() {
var self = this;
self.items = ko.observableArray([]);
}
$(function() {
var vm = new ViewModel();
ko.applyBindings(vm);
vm.items.push("追加アイテム"); // アイテムがフワッと追加される
};
function ViewModel() {
var self = this;
self.displayMessage = ko.observable(true);
}
$(function() {
var vm = new ViewModel();
ko.applyBindings(vm);
vm.displayMessage(false); // これでメッセージがフェードアウト
};
window.effects = (function($) {
var root = {}
, list = root.list = {}
;
// View に定義することで
// ・エフェクトの内容にちなんだ名前をつけることができる
// ・別の UI 部品でも使いまわせる
// というメリットもあります
list.fadeIn = function(elm) {
$(elm).hide().fadeIn();
};
list.fadeOut = function(elm) {
$(elm).fadeOut(300, function() { $(elm).remove() });
};
return root;
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment