选定一个最小的跟后面每个进行比较 若选定的不是最小值 则重新赋最小值
for(var j = 0;j<lis.length - 1;j++){
var min = j;
for(var i = j+1;i<lis.length;i++){
if(lis[min]>lis[i]){
min = i;
}
}
if(min !== j){
var temp = lis[min];
lis[min] = lis[j];
lis[j] = temp;
}
}
//定时器模拟for循环 参照for循环执行顺序
// for(model1; model2; model3){ 代码块 }
// model1 => model2 => 代码块 => (model3 => model2 => 代码块)$1 => $1... => model3 => model2 不成立 => 跳出
// 嵌套的for循环执行顺序 外层:for(m1; m2; m3){ 里层:如上 }
// m1 => m2 => (model1 => model2 => 代码块 => $1... => 跳出)$2 => m3 => m2 => $2 ... => m2 不成立,跳出
btn[1].onclick = function () {
var lis = box.children;
var j = 0, min = j, i = 0;
var timer = setInterval(function () {
if (j < lis.length - 1) {
if (i < lis.length) {
lis[i].classList.remove("pk"); //先全部移除 再给自己添加
if (lis[min].offsetHeight > lis[i].offsetHeight) {
lis[min].classList.remove("pk");
min = i;
lis[min].classList.add("pk");
}
i++;
if(lis[i]){ //判断i值是否超过最大值
lis[i].classList.add("pk");
}
} else {
lis[min].classList.remove("pk");
if (min !== j) {
var temp = lis[min].offsetLeft;
// lis[min].style.left = lis[j].offsetLeft + "px";
// lis[j].style.left = temp + "px";
slow(lis[min],lis[j].offsetLeft);
slow(lis[j],temp);
//min前面添加j 先往后添加 避免超出范围
box.insertBefore(lis[j],lis[min]);
//j前面添加min min一直是最小的
box.insertBefore(lis[min],lis[j]);
}
lis[j].classList.add("do");
j++;
min = j;
i = j + 1;
}
}else{
for(var k = 0;k<lis.length;k++){
if(!lis[k].classList.contains("do")){ //判断是否都添加完成标记
lis[k].classList.add("do");
}
}
clearInterval(timer);
}
}, 600)
}
假定前面已经排好序,用后面的元素与前面进行比较
for( var j = 1; j < arr.length; j++){
var temp = arr[j];
for(var i = j; i>0; i--){
if(temp < arr[i-1]){
arr[i] = arr[i-1];
}else{
break;
}
}
if(j!==i){
arr[i] = temp;
}
}
在要求的时间(duration) 内完成
通过比例计算
运动时长 运动距离
------------- = ------------ 比值等于1时说明到达终点
动画持续时间 需要运动的距离
box.onclick = function(){
animate(box,function(per){
box.style.width = 200 + 400*per + "px"; //宽度从原来的200增加到600 (per从0到1)
},3000)
}
//时间型动画 在要求的时间(duration)内完成
function animate(ele,func,duration){
if(ele.timer){
clearInterval(ele.timer);
}
var start = Date.now();
ele.timer = setInterval(function(){
var per = (Date.now() - start)/duration; //时间比例
if(per>=1){
per = 1; //等于1 说明到达终点
clearInterval(ele.timer); //清除定时器 语句后面的内容(func(per)依然会 执行
}
func(per);
},1000/60)
}
在时间型动画基础上增加一个函数(处理per值)
box.onclick = function(){
animate(box,function(per){
box.style.top = 400*per + "px";
},3000,getback/fn/makeEaseOut(bounce))
}
function animate(ele, func, duration, timing){
if(ele.timer){
clearInterval(ele.timer);
}
// 声明起始时间
var startTime = Date.now();
ele.timer = setInterval(function () {
// 获取时间比值
var per = (Date.now() - startTime)/duration;
if(per >= 1){
per = 1;
clearInterval(ele.timer);
}
func(timing(per));
}, 1000/60)
}
先慢后快
function fn(per){
return Math.pow(per, 3);
}
到终点后返回
function getback(per){
return -3.6*per*per + 4.6*per;
}
// 反转动画
function makeEaseOut(timing) {
return function(timeFraction) {
return 1 - timing(1 - timeFraction);
}
}
function bounce(timeFraction){
for(var a = 0,b = 1, result; 1; a += b, b/= 2){
if(timeFraction >= (7 - 4 * a) / 11){
return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2);
}
}
}
requestAnimationFrame
不需要设置时间,采用系统时间间隔,保持最佳绘制效率,能达到最佳的动画效果。
requestAnimationFrame
会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成。
当 requestAnimationFrame()
是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销
function animate(func,duration,timing){
var start = performance.now();
function fn(timer){
var per = (timer - start)/duration;
if(per>=1){
per = 1;
}
func(timing(per));
if(per<1){
requestAnimationFrame(fn);
}
}
requestAnimationFrame(fn); //没有1000/60
}