在Javascript中递归调用函数?

时间:2015-04-14 13:56:07

标签: javascript jquery html arrays recursion

我正在尝试使用HTML和jQuery创建一个小的交互式功能。为此,我一直在使用jQuery来更新和更改attr()和.text()。我想采用这种方法,因为我想要一种没有页面加载的更加无缝的感觉,因为它不是图像密集型的。

我创造了#34;场景"哪个有基本头衔。这些标题我放入一个数组然后随机播放(我希望它们的外观是随机的而不是重复)。

现在,当用户使用单选按钮进行选择时,场景才会改变(我可能会改变这一点,因为当前内容发生变化时单选按钮不会清除)。所以,点击这些选项的ID,在jQuery中我有" random_scene"功能并尝试再次调用此功能;基本上试图让它递归地逐步遍历数组,直到使用所有元素。

我下面有什么,有效,有点,但它有毛刺,有时会跳过一个选择而不会或在整个阵列中一步一步地降落到最后一个元素之前。

我需要帮助确定我尝试做的事情是否可能,以及是否有更好的方法来做我正在做的事情。我将包含我的整个js文件,以便您可以看到正在发生的事情。

$('#menu').accordion({  fillSpace: true, heightStyle: "content",  
event: 'mouseover', collapsible: true,  active: false, icons: false, animate: 750     });

$('.hover').mousemove(function(){
$(this).css('opacity', 1.0);
}).mouseout(function(){
    $(this).css('opacity', 0.5);    
}); 




 function rand_scene(scenes){

        if ( scenes[scenes.length-1] == "prison0" ){

            scenes.pop();


            $('img').attr('src', 'images/Prison.jpg');

            $('audio').attr('src', 'audio/');

            $('#choice1').text('choice content 1'); 

            $('#choice2').text('choice content 2');

            $('#choice3').text('choice content 3');

            $('#check1').click(function(){
                score += 2;
                return rand_scene(scenes);
            });

            $('#check2').click(function(){
                return rand_scene(scenes);
            });

            $('#check3').click(function(){
                score++;
                return rand_scene(scenes);
            });             
        }

        if ( scenes[scenes.length-1] == "socserv1" ){

            scenes.pop();

            $('img').attr('src', 'images/soc_serv.jpg');

            $('audio').attr('src', 'audio/');

            $('#choice1').text('choice content 1'); 

            $('#choice2').text('choice content 2');

            $('#choice3').text('choice content 3');

            $('#check1').click(function(){
                score += 3
                return rand_scene(scenes);      
            }); 

            $('#check2').click(function(){
                score++;
                return rand_scene(scenes);
            }); 

            $('#check3').click(function(){
                score += 2;
                return rand_scene(scenes);
            }); 

        }   

        if ( scenes[scenes.length-1] == "college3" ){

            scenes.pop();

            $('img').attr('src', 'images/college_debt.jpg');

            $('audio').attr('src', 'audio/');

            $('#choice1').text('choice content 1'); 

            $('#choice2').text('choice content 2');

            $('#choice3').text('choice content 3');

            $('#check1').click(function(){
                return rand_scene(scenes);      
            }); 

            $('#check2').click(function(){
                return rand_scene(scenes);
            }); 

            $('#check3').click(function(){
                return rand_scene(scenes);
            }); 

        }   

        if ( scenes[scenes.length-1] == "unity2" ){

            scenes.pop();

            $('img').attr('src', 'images/united.jpg');

            $('audio').attr('src', 'audio/');

            $('#choice1').text('choice content 1'); 

            $('#choice2').text('choice content 2');

            $('#choice3').text('choice content 3');

            $('#check1').click(function(){
                return rand_scene(scenes);          
            }); 

            $('#check2').click(function(){
                return rand_scene(scenes);
            }); 

            $('#check3').click(function(){
                return rand_scene(scenes);
            });     
        }   


}


var scenes = [ "prison0", "socserv1", "unity2", "college3" ];

function shuffle(array) {
    var counter = array.length;
    var temp = 0; 
    var index = 0;

    // While there are elements in the array
    while (counter > 0) {
        // Pick a random index
        index = Math.floor(Math.random() * counter);

        // Decrease counter by 1
        counter--;

        // And swap the last element with it
        temp = array[counter];
        array[counter] = array[index];
        array[index] = temp;
    }

    return array;
}

$(document).ready(function(){

shuffle(scenes);
//document.getElementById("menu_ops").innerHTML = scenes;

//var rand_page = Math.floor(Math.random() * 4);
var score = 0;
//var cont = 1;
rand_scene(scenes);

});

如您所见,选择了一个场景。某些属性和文本在#choice1 / 2/3中更改。然后用户使用#check1 / 2/3选择他们的选择,#check1 / 2/3是html中的单选按钮。点击单选按钮,他们的分数(他们内部不会看到它)得到更新,下一个"场景"应该从阵列中拉出来。

如上所述,它有点有用,但它往往会跳过" prison0"除非" prison0" scene是shuffled数组中的最后一个元素。

我必须通过调用这样的函数来遗漏某些东西。

感谢您的帮助,如果还有其他需要澄清的地方,请告诉我。谢谢。

这是小提琴链接。它看起来并不好看,但可以看到底部的选择无线电,有些场景确实会发生变化。我确实改变了else if语句。

jsfiddle

EDITADD:我自己想出了问题。在上面的代码中,我在选择新场景时从数组中弹出。在我自己的代码中,我将pop()移动到$()点击(function(){};

解决了所有问题并给了我需要的结果。谢谢大家的帮助!

2 个答案:

答案 0 :(得分:1)

我建议的第一件事就是改变第二,第三和第二。 if函数中rand_sceneelse if语句只有if,因此只有在前一个if语句不满意时才会运行。

这将解决您基本上可以满足该函数中所有var ar = [1,2,3,4]; if (ar[ar.length - 1] == 4) { console.log("four"); ar.pop(); } if (ar[ar.length - 1] == 3) { console.log("three"); ar.pop(); } if (ar[ar.length - 1] == 2) { console.log("two"); ar.pop(); } if (ar[ar.length - 1] == 1) { console.log("one"); ar.pop(); } 语句的问题。举个例子......

if

第一个if语句将评估为true,因为数组中的最后一个元素是4.这将记录"四个"然后删除数组的最后一个元素。

然后,下一个if语句也将评估为true,因为数组的最后一个元素现在为3.

等。

但是,如果您将其更改为此,那么它将停在一个真正的var ar = [1,2,3,4]; if (ar[ar.length - 1] == 4) { console.log("four"); ar.pop(); } else if (ar[ar.length - 1] == 3) { console.log("three"); ar.pop(); } else if (ar[ar.length - 1] == 2) { console.log("two"); ar.pop(); } else if (ar[ar.length - 1] == 1) { console.log("one"); ar.pop(); } 语句中,而不是全部运行...

var ar = [1,2,3,4];
var value = ar.pop();

switch(value) {
    case 1:
        console.log("one");
        break;

    case 2:
        console.log("two");
        break;

    case 3:
        console.log("three");
        break;

    case 4:
        console.log("four");
        break;
}

在不知道你的代码中有多少是伪的,以及文字的多少我可以帮助进一步整理,但是那里有很多可以删除的重复,使代码更清洁并且更易于阅读和维护。

这显然只是一个例子,但它与上面相同,但是已经减少......

{{1}}

答案 1 :(得分:0)

如果你把它放在小提琴里会很有帮助。但是从我收集的内容来看,您可以做出两项改进(其中一项是我认为递归的意思)

1)您的随机播放功能并不是最好的。因为索引只能在[0, counter]而不是[0, array.length]的范围内,所以它会不正当地将shuffle偏向较小的索引元素。这意味着它不太可能得到真正的洗牌。什么可能更好的说,

index = Math.floor(Math.random() * scenes.length);

确保所有元素都有(更)公平的机会被洗牌。

2)此问题不会要求递归。它可以通过简单的循环完成。你说的是rand_scene(scenes);,我认为你打算开始你的递归调用,但这是不必要的。相反,您可以简单地将该调用放入while循环中,并且只要数组中有元素就运行。

while(scenes.length){
    rand_scene(scenes);
}

由于rand_scene(scenes);每次都会弹出,我们可以放心,在某些时候,scenes.length将为0,循环将会中断。