如何使用jQuery Mobile在某些页面上运行计时器?

时间:2014-06-10 20:28:25

标签: javascript jquery html jquery-mobile timer

我有一个小测验应用程序,它使用jQuery Mobile。我正在创建一个计时器,我希望从0秒到1小时运行。虽然,我希望计时器仅在用户查看某些页面时运行,即仅在用户遇到问题时运行。因为在回答问题之后,会出现另一个带有动画的页面,然后转到另一个页面,这是解释。我在问题的标题部分显示计时器。我有一个像这样的HTML:

<div id="q1" data-role="page" data-add-back-btn="true" data-back-btn-text="Home">
                <div data-role="header"  data-position="fixed"  data-tap-toggle="false">
                    <h1><img src="images/timer.png"> <span id="timer"></span></h1>
                </div>
          <!--Here comes some other code related to the quiz question-->
</div>

我有30个问题,每个人的身份证都是以&q; q&#39;后跟一个数字,如示例q1中所示。在每个人的头上,我都有一个名为&#34; timer&#34;的span元素。我希望数字显示在哪里。

        var timestamp;
        var interval = 1;
        var initTimer = true;
        var timerEl = $('span#timer');
        var qNumber;
        var qCorrect;
        var qFalse;

        function relocateTimer(newEl) {
            timerEl.prependTo(newEl);
        }

        function pad(n) { return ("0" + n).slice(-2); }

        Number.prototype.pad = function (len) {
            return (new Array(len+1).join("0") + this).slice(-len);
        }

        $(document).on("pagechange", function(event, ui) {
            if (($.mobile.activePage[0].id != "correctGIF") && ($.mobile.activePage[0].id != "wrongGIF")) {
                page = $.mobile.activePage[0].id;

                if (page.match(/\d+$/) != null) {
                    qNumber = page.match(/\d+$/)[0];
                    qCorrect = q.concat(qNumber, 'Correct');
                    qFalse = q.concat(qNumber, 'False');
                }

                if (page !== qCorrect || page !== qFalse) {
                     if (page == "q1") {
                         timestamp = new Date(0, 0, 0, 0, 0, 0);
                         if (initTimer) {
                            setInterval(function() {
                                timestamp = new Date(timestamp.getTime() + interval * 1000);
                            document.getElementById('timer').innerHTML = timestamp.getMinutes().pad(2) + ':' + timestamp.getSeconds().pad(2);
                            }, Math.abs(interval) * 1000);

                            initTimer = false;
                         }
                     }
                }
          }

我有类似上面的代码。我希望在用户问题1(q1)时重置计时器。当他/她处于其他问题时,从q2到q30,我想要显示计时器,并继续从最后一次离开的时间。因此,该功能应该包含在if (page !== qCorrect || page !== qFalse)内,但我不知道如何实现它。任何人,任何想法?

编辑1:

正如我所说,我有30个问题,他们在q1到q30之间有id。我希望计时器在q1中重置,或者如果1小时过去,它应该显示一个警报并移动到主页,其中有一个id home。因此,只有当前活动页面位于q1到q30之间时,我的代码才会进入if (page !== qCorrect || page !== qFalse)内部。这就是为什么我在那里检查当前页面是否为q1,如果它是我激活计时器。所以,我从答案中理解的是,我需要做那样的事情:

if (page !== qCorrect || page !== qFalse) {
    var curpage = '#'.concat(page);
    timestamp = new Date(0, 0, 0, 0, 0, 0);

    $(curpage).on("pagebeforeshow", function(event) 
    { 
         var element = $(this).find("span#timer");
         if (initTimer) {
                setInterval(function() {
                timestamp = new Date(timestamp.getTime() + interval * 1000);
            document.getElementById(element).innerHTML = timestamp.getMinutes().pad(2) + ':' + timestamp.getSeconds().pad(2);
                }, Math.abs(interval) * 1000);

                initTimer = false;
         }
    }
}

虽然,不知道这是否正确,并且不知道如何在pagehide事件上停止计时器。 });

编辑2:

在你的好榜样之后,我为自己尝试了一些东西。我有下面的代码,但它似乎没有工作。我的意思是它不会停止计时器。在每个问题之后,我展示和动画是否是正确答案或错误(#correctGIF和#wrongGIF页面),然后我显示答案。关键是在这些页面中,未显示计时器,这是必须的。但是当我到达下一个问题时,它不是从之前的左边时间继续,而是从之前的剩余时间再加上3-4秒。请注意,我的动画(GIF)每3秒钟一次。也许计时器在显示时是活动的。

var timestamp = new Date(0, 0, 0, 0, 0, 0);
var interval = 1;
var initTimer = true;
var timer = null;

function pad(n) { return ("0" + n).slice(-2); }

Number.prototype.pad = function (len) {
    return (new Array(len+1).join("0") + this).slice(-len);
}

function startTimer() {
    var currentPage = $.mobile.activePage[0].id;
    if (timer == null) {
        var $timer = $("#"+currentPage +" span#timer");
        timer = setInterval(function() { showTimer() }, 1000);
    }
}

function stopTimer() {
    if (timer !== null) {
        clearInterval(timer);
        timer = null;
    }
}

function showTimer() {
    timestamp = new Date(timestamp.getTime() + interval * 1000);
    var currentPage = $.mobile.activePage[0].id;
    var $timer = $("#"+currentPage +" span#imter");
    $timer.html(timestamp.getMinutes().pad(2) + ':' + timestamp.getSeconds().pad(2));
    return false;
}


$(document).on("pagechange", function(event, ui) {

    $("[id^=q]").on('pagebeforeshow', function() {
        var currentPage = $.mobile.activePage[0].id;
        console.log("Current page is: " + currentPage);

        var correctIndex = currentPage.indexOf('Correct');
        var falseIndex = currentPage.indexOf('False');

        if (correctIndex > -1  || falseIndex > -1) {
            stopTimer();
        } else {
            startTimer();
        }
    });

    // I have some more code down here, checking which page is currently active and
    // acting accordingly. This part is crucial for my app.

});

解决:

似乎计时器在动画期间运行,添加了stopTimer();到#correctGIF和#wrongGIF使它工作。谢谢!

1 个答案:

答案 0 :(得分:0)

我认为您应该在更改页面时查看来自jQuery Mobile的事件:

特别是

http://api.jquerymobile.com/category/events/&#39; pagebeforeshow&#39;(pagebeforeshow)。

在您的情况下&#39;选择器&#39;将是问题中div的类或id:

$(".selector").on("pagebeforeshow", function(event) 
{ 
     var element = $(this).find("span#timer");
     //start element animation here, start the timer
});

此外,你应该在这个功能中杀死你的计时器:

$(".selector").on("pagehide", function( event ) { ... });

P.S。将在修改问题后或评论后更新答案。

Jsfiddle.net示例在这里:http://jsfiddle.net/floradu88/sW8kv/1/

使用代码进行编辑,只需将其添加到aaa.html并在浏览器中运行:

<!DOCTYPE html> 
<html> 
    <head> 
    <title>My Page</title> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
</head> 
<body> 

<div data-role="page">

    <div data-role="header">
        <h1>My Title</h1>
    </div><!-- /header -->

    <div data-role="content">   
        <p>Hello world</p>
    <a href="#" data-role="button" data-icon="star" onclick="showPage1();">Star button</a>      
    </div><!-- /content -->

</div><!-- /page -->

<div id="q1" data-role="page" data-add-back-btn="true" data-back-btn-text="Home">
                <div data-role="header"  data-position="fixed"  data-tap-toggle="false">
                    <h1><img data-icon="arrow-l"> <span id="timer">Timer not started</span></h1>
                </div>
          <!--Here comes some other code related to the quiz question-->
          Question 1 - text
          <a href="#" data-role="button" data-icon="star" onclick="showNextPage()">Next</a>
          <a href="#" data-role="button" data-icon="star" onclick="showAnswerPage()">Show answer</a>
</div>

<div id="q1Answer" data-role="page" data-add-back-btn="true" data-back-btn-text="Home">


                <div data-role="header"  data-position="fixed"  data-tap-toggle="false">
                    <h1><img data-icon="arrow-l"> <span id="timer">Timer not started</span></h1>
                </div>
          <!--Here comes some other code related to the quiz question-->
          Question 1 answer 
          <a href="#" data-role="button" data-icon="star" onclick="showNextPage()">Next</a>
</div>

<div id="q2" data-role="page" data-add-back-btn="true" data-back-btn-text="Home">
                <div data-role="header"  data-position="fixed"  data-tap-toggle="false">
                    <h1><img data-icon="arrow-l"> <span id="timer">Timer not started</span></h1>
                </div>
          <!--Here comes some other code related to the quiz question-->
          Question 2 - text
          <a href="#" data-role="button" data-icon="star" onclick="showNextPage()">Next</a>
          <a href="#" data-role="button" data-icon="star" onclick="showAnswerPage()">Show answer</a>
</div>

<div id="q2Answer" data-role="page" data-add-back-btn="true" data-back-btn-text="Home">
    <div data-role="header"  data-position="fixed"  data-tap-toggle="false">
                    <h1><img data-icon="arrow-l"> <span id="timer">Timer not started</span></h1>
                </div>
                Question 2 answer 
          <!--Here comes some other code related to the quiz question-->
          <a href="#" data-role="button" data-icon="star" onclick="showNextPage()">Next</a>
</div>

<div id="q3" data-role="page" data-add-back-btn="true" data-back-btn-text="Home">
                <div data-role="header"  data-position="fixed"  data-tap-toggle="false">
                    <h1><img data-icon="arrow-l"> <span id="timer">Timer not started</span></h1>
                </div>
          <!--Here comes some other code related to the quiz question-->
          Question 3 - text
          <a href="#" data-role="button" data-icon="star" onclick="showNextPage()">Next</a>
          <a href="#" data-role="button" data-icon="star" onclick="showAnswerPage()">Show answer</a>
</div>

<div id="q3Answer" data-role="page" data-add-back-btn="true" data-back-btn-text="Home">
               <div data-role="header"  data-position="fixed"  data-tap-toggle="false">
                    <h1><img data-icon="arrow-l"> <span id="timer">Timer not started</span></h1>
                </div>
                Question 3 answer 
          <!--Here comes some other code related to the quiz question-->
          <a href="#" data-role="button" data-icon="star" onclick="showNextPage()">Next</a>
</div>

<script type="text/javascript">
 var timer = null;
 var actualValue = 0;
 var questionNo = 3;

 function showNextPage(){
    var currentPage = $.mobile.activePage[0].id;

    var part = currentPage.substr(1);
    var index = part.indexOf('Answer');
    if (index > -1) {
       part = part.substr(0,index);
    }
    var number = parseInt(part);

    if (number + 1 <= questionNo) {
        var nextPageId = "#q"+ (number + 1);

        $.mobile.changePage($(nextPageId));
    } else {
       //ended questionnaire
       alert("ended questionnaire");
    }
 }

 function showAnswerPage(){

    var currentPage = $.mobile.activePage[0].id;

    var part = currentPage.substr(1);
    var number = parseInt(part);
    var nextPageId = "#q"+ number + "Answer";

    var index = currentPage.indexOf('Answer');

    stopTimer();

    $.mobile.changePage($(nextPageId));
 }

 $("[id^=q]").on('pagebeforeshow', function(){
    var currentPage = $.mobile.activePage[0].id;

    var index = currentPage.indexOf('Answer');

    if (index > -1) {
        stopTimer();
    } else {
        startTimer();
    }
 });

 function startTimer(){
    var currentPage = $.mobile.activePage[0].id;
    if (timer == null) {
        var $timer = $("#"+currentPage +" span#timer");
        timer = setInterval(function(){ showClock() }, 1000);
    }
 }

 function stopTimer(){

    if (timer !== null) {
        clearInterval(timer);
        timer = null;
    }
 }

 function showPage1(){
    $.mobile.changePage($("#q1"));
    return false;
}

function showClock(){
   console.log(actualValue);
   actualValue = actualValue + 1;
   var currentPage = $.mobile.activePage[0].id;

   var $timer = $("#"+currentPage +" span#timer");
   $timer.html(actualValue +' s elapsed');
   return false;
}
</script>

</body>
</html>