我很难理解为什么过渡不像预期的那样。它应该应用"from",然后将"transition"添加到"el",然后它应该运行"to",最后onTransitionEnd它应该运行"callback"(前缀为清除过渡属性的代码)。
在Webkit浏览器中,它可以正确地转换slideDown,但是slideUp是即时的。
尔格?
JSFiddle: http://jsfiddle.net/enhTd/
var $ = function(query) {
var a = [],
n = document.querySelectorAll(query),
l = n.length;
for( var i = 0; i<l; i++){
a.push(n[i]);
}
if(l>1) {return a;} else {return a[0];}
},
$id = function(query) { return document.getElementById(query);},
getSupportedPropertyName = function(properties) {
for (var i = 0; i < properties.length; i++) {
if (typeof document.body.style[properties[i]] != "undefined") {
return properties[i];
}
}
return null;
},
vendorTransitions = ["transition", "msTransition", "webkitTransition", "MozTransition", "OTransition"],
prefixedTransitionProperty = getSupportedPropertyName(vendorTransitions),
transition = function(opts){
opts.from && opts.from();
if(prefixedTransitionProperty){
var c = opts.callback || function() {},
el = opts.el,
cb = function(event){
var ev = event, callback = c;
ev.target.removeEventListener(prefixedTransitionProperty+"End", cb);
ev.target.style[prefixedTransitionProperty] = "none";
if(callback) {
callback(ev);
}
};
el.style[prefixedTransitionProperty] = opts.transition || "";
el.addEventListener(prefixedTransitionProperty+"End", cb);
}
opts.to && opts.to();
},
slideDown = function(el, t){
var style = el.style,
h, oh = el.offsetHeight,
t = t || 1000;
//Grab real height
style.height = "";
h = el.offsetHeight;
transition({
"el": el,
transition: "height "+t+"ms ease",
from: function() {
style.height = oh+"px";
},
to: function(){
style.overflow = "hidden";
style.height = h+"px";
},
callback: function(event){
event.target.style.height = "";
}
});
},
slideUp = function(el, t){
var style = el.style,
h = el.offsetHeight,
t = t || 1000;
transition({
"el": el,
transition: "height "+t+"ms ease",
from: function() {
style.height = h+"px";
},
to: function(){
style.overflow = "hidden";
style.height = "0";
}
});
},
slideToggle = function(el, t){
var t = t || 1000;
if(el.style.height=="0px"){
slideDown(el, t);
} else {
slideUp(el, t);
}
};
slideUp($id("intro"));
$("a[href='#intro']").forEach(function(el){
el.addEventListener("click", function(ev) {
ev.preventDefault();
if(ev.target.classList.contains("hide")){
slideUp($(ev.target.hash));
} else {
slideDown($(ev.target.hash));
}
});
});
$("li h3").forEach(function(el){
el.addEventListener("click", function(ev) {
ev.preventDefault();
slideToggle(ev.target.parentNode);
});
});
在某些浏览器中,您不能仅仅设置初始状态,设置最终状态并期望CSS转换工作。
相反,必须设置初始状态,然后在设置最终状态并期望转换运行之前必须呈现它。使其呈现的最简单方法是返回到事件循环,然后在setTimeout()
调用后执行任何进一步处理(如设置最终状态)。
试试这个:http://jsfiddle.net/enhTd/1/(在chrome和ff中测试)
first:做jfriend00所说的:
在你的过渡函数:
transition = function (opts) {
..
setTimeout(function() {
opts.to && opts.to();
}, 1)
}
second: slideDown()
方法中不需要回调:
slideDown = function (el, t) {
..
take this out:
/*callback: function (event) {
event.target.style.height = "";
}*/
});
从设计的角度来看…回调函数没有添加任何值。当涉及到过渡时,你应该从你离开的地方继续。
third: disable slide down when slide already down. 但是我把它留给你。