动态循环JSON,并在设置间隔后显示和隐藏对象元素

Dynamically loop JSON and show and hide object elements after set interval

本文关键字:显示 隐藏 元素 对象 JSON 循环 设置 动态      更新时间:2023-09-26

JavaScript/jQuery新手在这里。。。我正在努力循环使用JSON文件,并使用jQuery成功地呈现顶级项。这里的目的是显示单个元素,然后在显示连续的元素之前将其淡出。但是,我的脚本只呈现最后一个元素。你知道我在这里做错了什么吗?

JSON文件-x.JSON

{"questions":[
    {
    "q":"Question1...?",
    "a": [
    "Answer 1a",
    "Answer 1b",
    "Answer 1c",
    "Answer 1d"
]
},
{
    "q":"Question2...?",
    "a": [
    "Answer 2a",
    "Answer 2b",
    "Answer 2c",
    "Answer 2d"
]
}
]}

JavaScript文件-x.js

$(document).ready( function () {
    $.getJSON('x.json', function (jsondata) {
        // compute total number of questions in JSON file
        var totalQuestions = jsondata.questions.length;
        $.each(jsondata.questions, function (i) {
            var questionNumber = i + 1; // add one since indicies start at 0
            var questionContent = jsondata.questions[i]["q"];
            var answerContent = ''; 
            // generate questions progress HTML text
            var questionHTML = '<div class="questionCount">Question <span class="current">' + questionNumber +'</span> of <span class="total">' + totalQuestions + '</span>';
            // generate question HTML text
            questionHTML += '</div><h3>' + questionNumber + '. ' + questionContent + '</h3>';
            console.log(JSON.stringify(jsondata.questions[i]["q"]));
            var answersHTML = '<ul type="A" class="answerswers">';
            $.each(jsondata.questions[i]["a"], function (k) {
                answerContent = jsondata.questions[i]["a"][k];
                answersHTML += '<li><input type="radio"><label>' + answerContent + '</label></li>';
            }); 
            answersHTML += '</ul></li>';
            questionHTML += answersHTML;
            console.log(questionHTML);
            $("#placeholder").html(questionHTML);
            setInterval(function () {
                $("#placeholder").html(questionHTML);
                $("#placeholder").fadeIn(6000).delay(3000).fadeOut(1000);
            }, 5000);
        }); 
    }); 
});

HTML文件-x.HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>JSON Sample</title>
</head>
<body>
    <div id="placeholder"></div>
    <script src="js/jquery.js"></script>
    <script src="x.js"></script>
</body>
</html>

首先我假设,您希望将所有问题放在同一位置,对吗?添加一些CSS如下:

#placeholder {
    position: relative;
}
#placeholder .question {
    position: absolute;
}

我把你的问题和相应的答案封装在.question类的DIV中。将jQuery代码更改为以下代码:

            [...]
            // generate questions progress HTML text
            var questionHTML = '<div class="question" style="display:none;">
                    <div class="questionCount">Question <span class="current">' + questionNumber + '</span> of <span class="total">' + totalQuestions + '</span>';
            [...]
            answersHTML += '</ul></li>
                </div>';
            [...]
            console.log(questionHTML);
            $("#placeholder").html(questionHTML);
        }); // end foreach
    }); // end .getJSON callback
    animate();
}); // end $(document).ready callback
function animate(current) {
    var count = $('#placeholder .question').length;
    if (isNaN(current)) { current = 0; }
    console.log(current);
    animateOne($('#placeholder .question').get(current), function() {
        animate(++current % count);
    });
};
function animateOne(el, callback) {
    $(el).fadeIn(6000).delay(3000).fadeOut(1000, function() {
        callback();
    });
};

试试JSFiddle:http://jsfiddle.net/97buosve/7/

替代动画

你可以使用这个替代函数,在淡出时同时看到两个问题。我只是将回调从fadeOut移回fadeIn。。。

function animateOne(el, callback) {
    $(el).fadeIn(6000, function() {
        callback();
    }).delay(3000).fadeOut(1000);
};

试试JSFiddle:http://jsfiddle.net/97buosve/8/

没有循环的替代动画

function animate(current) {
    var count = $('#placeholder .question').length;
    if (isNaN(current)) { current = 0; }
    console.log(current);
    animateOne(
        $('#placeholder .question').get(current), // question to animate
        (current +1 < count), // hide it after fadeIn, only if it isn't the last question
        function() { // callback to animate the next question
            if (current +1 < count) { // prevent loop, only set callback if it isn't the last question
                animate(++current % count);
            }
        }
    );
};
function animateOne(el, hideItAfter, callback) {
    $(el).fadeIn(6000, function() {
        callback();
    });
    if (hideItAfter) {
        $(el).delay(3000).fadeOut(1000);
    }
}

http://jsfiddle.net/97buosve/9/

两个错误:

1) setInterval不是一个"暂停"函数。它会立即返回,因此您的循环以毫秒为单位闪烁(因此您只能看到最后一次重复)。

2) 你没有设置一个闭包。查看这个常见的问题,关于如何在循环内的闭包中传递变量:循环内的JavaScript闭包——一个简单的实用示例