我正在尝试将shellsort算法可视化。
function shellSort (a) {
for (var h = a.length; h = parseInt(h / 2);) {
for (var i = h; i < a.length; i++) {
var k = getInt(a[i].id);
var helper = a[i];
for (var j = i; j >= h && k < getInt(a[j - h].id); j -= h){
var idA = a[j].id;
var idB = a[j - h].id;
setTimeout(function(){
animatTthis($('#' + idA), 500);
animatTthis($('#' + idB), 500);
console.log('animate!');
},250);
a[j] = a[j - h];
}
a[j] = helper;
}
}
return a;
}
首先,我创建随机数,并将它们作为p-tag添加到div中。之后,我将所有div与适配类推送到一个Array中,该Array被赋予上面的shellsort函数。 这很好但我无法使动画正常工作。
function animatTthis(targetElement, speed) {
$(targetElement).animate({ top: "50px"},
{
duration: speed,
complete: function ()
{
setTimeout(function(){
$(targetElement).animate({ top: "0px" },{
duration: speed,
complete: function (){
console.log('animate!');
}
});
},500);
}
});
};
它只会动画循环中最后两个Div。
我的意图是交换掉的两个Div再次向下滑动。在此之后,应该继续进行解决方案。
我尝试了许多不同的解决方案,但我无法按照我想要的方式工作。
完成的版本应该在视觉上交换两个div ..所以,如果你有一个快速的解决方案或链接对我来说会很棒。
提前致谢。
编辑:
使用的HTML和CSS:
<!DOCTYPE html>
<html>
<head>
<script src="jquery-3.0.0.js"></script>
<script src="script.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/color/jquery.color-2.1.2.js"></script>
<link rel="stylesheet" href="stylesheet.css">
<title>Shell Sort</title>
</head>
<body>
<h1 >Shell- sort</h1>
<button id='randomNumbers'>Numbers!</button> // creeates random numbers
<button id='okay'>Okay!</button> //starts the shellsort
<div id='container'>
<div id="element1" class="test"><p class='value' id='e1ID'></p></div>
<div id="element2" class="test"><p class='value' id='e2ID'></p></div>
<div id="element3" class="test"><p class='value' id='e3ID'></p></div>
<div id="element4" class="test"><p class='value' id='e4ID'></p></div>
<div id="element5" class="test"><p class='value' id='e5ID'></p></div>
<div id="element6" class="test"><p class='value' id='e6ID'></p></div>
</div>
</body>
</html>
CSS:
h1{
color:red;
}
.value{
margin: 0;
text-align: center;
line-height:75px;
font-size: 30px;
font-weight: bold;
}
.test{
background-color: red;
height: 75px;
width: 75px;
position: relative;
float:left;
margin: 10px;
border-radius: 50%;
}
这里没有任何功能,但也许它会有所帮助.. :)
jquery代码:
$(document).ready(function(){
//#############---giveRandomNumbers----#############
$("#randomNumbers").click(function(){
var numbers = [];
for(var i = 0; i < 6; i++){
var $random = Math.floor((Math.random() * 100) + 1);
numbers.push($random);
}
for(var int = 0; int < numbers.length; int++){
$('#e'+(int + 1)+'ID').text(numbers[int]);
}
});
$('#okay').click(function(){
var $ids = $('.test');
shellSort($ids);
for(var int = 0; int < $ids.length; int++){
console.log(getInt($ids[int].id));
$("#container").append($ids[int]);
}
});
//#############---getIntegerOfDiv----#############
function getInt(id) {
var $number = parseInt($('#'+ id).find("p").text());
return $number;
};
//#############---animationCarry----#############
function createAnimation(a, b) {
return function() {
animatTthis($('#' + a), 500);
animatTthis($('#' + b), 500);
};
}
//#############---animation----#############
function animatTthis(targetElement, speed) {
$(targetElement).animate({ top: "50px"},
{
duration: speed,
complete: function (){
setTimeout(function(){
$(targetElement).animate({ top: "0px" },{
duration: speed,
complete: function (){
console.log('animate!');
}
});
},500);
}
});
};
//#############---shellSort----#############
function shellSort (a) {
for (var h = a.length; h = parseInt(h / 2);) {
for (var i = h; i < a.length; i++) {
var k = getInt(a[i].id);
var helper = a[i];
for (var j = i; j >= h && k < getInt(a[j - h].id); j -= h){
a[j] = a[j - h];
var idA = a[j].id;
var idB = a[j - h].id;
setTimeout(createAnimation(idA, idB), 250);
}
a[j] = helper;
}
}
return a;
}
});
答案 0 :(得分:0)
看起来,超时中使用的变量只是被引用 - 所以对于每个循环,为当前val(= expected)设置新的超时+以前创建的超时函数的函数中的值也被修改(=意外,我猜)。
一种可能的解决方案是不异步进行动画。 也许它也可以通过“currying”函数ala
创建一个函数function createAnimation(a, b) {
return function() {
animatTthis($('#' + a), 500);
animatTthis($('#' + b), 500);
};
}
以我们的方式:
setTimeout(createAnimation(idA, idB), 250);
希望这有帮助
编辑:动画同时是你要求的另一个问题。 无论如何:问题是,迭代比250ms快得多,所以所有的动画几乎同时开始。
您需要一个接一个地通过动画回调对动画进行排队。我的建议是首先进行排序并收集如何动画的信息。之后,您可以根据需要创建一个链式函数进行动画处理。
我创建了一个示例,它通过“动画师”替换了一些原始方法,该动画师能够收集所需信息并在之后执行动画:
var Animator = {
toAnimate: [],
add: function(a, b) {
Animator.toAnimate.push({
a: '#' + a,
b: '#' + b
});
},
execute: function() {
var lastCallback = function() {
Animator.toAnimate = [];
};
for (var idx = 0; idx<Animator.toAnimate.length; idx++) {
var elem = Animator.toAnimate[idx];
var animateB = Animator.createAnimation(elem.b, 500, lastCallback);
var animateA = Animator.createAnimation(elem.a, 500, animateB);
lastCallback = animateA;
}
lastCallback();
},
createAnimation: function(id, speed, cb) {
console.log('creating animation for ' + id);
return function() {
$(id).animate({top: '50px'}, speed, function() {
$(id).animate({top: '0px'}, speed, function() {
if (typeof(cb) === 'function') {
cb();
}
});
});
}
}
}
这似乎从动画的角度来看,结帐这个小提琴:https://jsfiddle.net/91Lp7k90/
除此之外,elemt id似乎不正确,这也是我添加一些控制台输出的原因......