创建一个 jquery 秒表,该秒表在用户焦点时开始,在焦点移出时停止并开始新的计时器

发布于 2024-11-09 00:49:46 字数 1433 浏览 0 评论 0原文

我正在构建一个简单的网络应用程序,允许用户自我测验数学问题。用户首先选择她想要做的问题类型,然后选择她想要做的问题数量。

当用户解决问题时,我想计算完成每个问题所需的时间。这是在页面上显示问题的代码:

function displayMult ($i)
{
echo '<table class="basic">';
    for($k=0; $k < $i; ++$k) // display problems
    {
        $user_response[$k] = 'user_response' . $k ;
        echo '<tr>';
        echo '<td>' . number_format($_SESSION['mult_one'][$k]) . '</td>';
        echo '<td>'. ' x ' . '</td>';
        echo '<td>' . number_format($_SESSION['mult_two'][$k]) . '</td>';
        echo '<td>' . ' =   <input type="text" class="field" name="user_response' . $k . '"' . 'id="u_r' . $k . '" />' . '</td>';
        echo '<td id="timer_' . $k . '">test</td>';
        echo '</tr>';
    }
echo '</table>';
}

这是我对用户响应进行计时的 jQuery。我遇到的问题是 1) 我无法找到一种写入方法来始终选择正确的计时器 ID 传递到秒表功能中,以及 2) 停止旧计时器并开始新计时器。当前代码只会对第一个问题进行计时,然后当用户单击下一个问题的输入字段时正确停止计时器。

$(document).ready(function() {
    $('.field').focus(stopwatch('#timer_0'));
});

function stopwatch(container) {
  var interval;
  return function() {
    if (interval) {
       clearInterval(interval); 
    }
    else{
        var count = 0;
        interval = setInterval(function() {
            count++;
            $(container).html(count + ' seconds');
        }, 1000);
    }
  };
}

我是 jquery 新手,因此任何帮助和见解将不胜感激!提前致谢。

I'm in the process of building a simple web app that allows a user to quiz his/herself on math problems. The user first chooses the type of problem she'd like to do and then how many she'd like to do.

As the user is going through the problems, I'd like to time how long it takes to complete each problem. This is the code that displays the problems on the page:

function displayMult ($i)
{
echo '<table class="basic">';
    for($k=0; $k < $i; ++$k) // display problems
    {
        $user_response[$k] = 'user_response' . $k ;
        echo '<tr>';
        echo '<td>' . number_format($_SESSION['mult_one'][$k]) . '</td>';
        echo '<td>'. ' x ' . '</td>';
        echo '<td>' . number_format($_SESSION['mult_two'][$k]) . '</td>';
        echo '<td>' . ' =   <input type="text" class="field" name="user_response' . $k . '"' . 'id="u_r' . $k . '" />' . '</td>';
        echo '<td id="timer_' . $k . '">test</td>';
        echo '</tr>';
    }
echo '</table>';
}

And this is the jQuery I have that times the user responses. The problem I'm having is that 1) I can't figure out a way to write to always select the correct timer ID to pass into the stopwatch function and 2) stop old timer and begin new one. The current code will only time the first question and then correctly stop the timer when the user clicks on the input field for the next question.

$(document).ready(function() {
    $('.field').focus(stopwatch('#timer_0'));
});

function stopwatch(container) {
  var interval;
  return function() {
    if (interval) {
       clearInterval(interval); 
    }
    else{
        var count = 0;
        interval = setInterval(function() {
            count++;
            $(container).html(count + ' seconds');
        }, 1000);
    }
  };
}

I'm new to jquery so any help and insight would be greatly appreciated! Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦年海沫深 2024-11-16 00:49:46

这里是我的尝试

var timer_id;

$(document).ready(function() {
    $('.field').focus(function() {
        $(this).addClass('active_input');
        timer_id = setInterval('tick()', 1000);
    }).blur(function() {
        $(this).removeClass('active_input');
        clearTimeout(timer_id);
    });
});

function tick() {
    var id_n = $('.active_input').attr('id').substring(3);
    var t_td = $('#timer_' + id_n);
    var t = parseInt(t_td.text(), 10);
    if (isNaN(t)) {
        t = '1 second';
    } else {
        t++;
        t += ' seconds'
    }
    t_td.text(t);
}

Here's my go at it

var timer_id;

$(document).ready(function() {
    $('.field').focus(function() {
        $(this).addClass('active_input');
        timer_id = setInterval('tick()', 1000);
    }).blur(function() {
        $(this).removeClass('active_input');
        clearTimeout(timer_id);
    });
});

function tick() {
    var id_n = $('.active_input').attr('id').substring(3);
    var t_td = $('#timer_' + id_n);
    var t = parseInt(t_td.text(), 10);
    if (isNaN(t)) {
        t = '1 second';
    } else {
        t++;
        t += ' seconds'
    }
    t_td.text(t);
}
一个人练习一个人 2024-11-16 00:49:46

第 1 部分:
您可能想要做的不是在秒表中返回函数,而是在 focus() 调用中放置一个内联函数,该函数从字段中获取有关应发送到哪个计时器的一些信息。如果您至少使用 jQuery 1.5,则可以在 HTML 中设置一个属性,您可以使用 jquery .data() 方法检索该属性。

第 2 部分:
您在这里遇到的问题是,当您稍后调用计数和间隔句柄时,它们不在正确的范围内。实际上,您可以完全不间隔地执行此操作,只需再次使用 .data() 在计时器元素上存储开始时间,然后将处理程序附加到每个字段的模糊事件以停止它并显示结果。

这是 PHP:

function displayMult ($i)
{
echo '<table class="basic">';
    for($k=0; $k < $i; ++$k) // display problems
    {
        $user_response[$k] = 'user_response' . $k ;
        echo '<tr>';
        echo '<td>' . number_format($_SESSION['mult_one'][$k]) . '</td>';
        echo '<td>'. ' x ' . '</td>';
        echo '<td>' . number_format($_SESSION['mult_two'][$k]) . '</td>';
        echo '<td>' . ' =   <input data-timer="#timer_' . $k . '" type="text" class="field" name="user_response' . $k . '"' . 'id="u_r' . $k . '" />' . '</td>';
        echo '<td id="timer_' . $k . '">test</td>';
        echo '</tr>';
    }
echo '</table>';
}

这是 JS:

$(document).ready(function() {
    $('.field').focus(function() {
        var timer_id = $(this).data("timer");
        stopwatch("#" + timer_id);
    });
    $('.field').blur(function() {
        var timer_id = $(this).data("timer");
        stopwatch("#" + timer_id);
    });
});

function stopwatch(container_id) {
  var $container = $(container_id);
  var time_now = new Date();
  var time_started = $container.data("time");
  if (time_started) {
    time_taken = time_now - time_started; // This is in milliseconds
    $container.html(time_taken / 1000 + ' seconds');
  }
  else {
    $container.data("time", time_now);
  }
}

Part 1:
Rather than returning a function in stopwatch, what you probably want to do is put an inline function in the focus() call that gets some info from the field about which timer it should be sent to. If you're using at least jQuery 1.5, you can set an attribute in the HTML that you can retrieve using the jquery .data() method.

Part 2:
The problem you're running into here is the count and interval handle aren't in the right scope when you call them later. You can actually do this without intervals at all by just using .data() again to store a start time on the timer element, and then attach a handler to each field's blur event to stop it and display the result.

Here's the PHP:

function displayMult ($i)
{
echo '<table class="basic">';
    for($k=0; $k < $i; ++$k) // display problems
    {
        $user_response[$k] = 'user_response' . $k ;
        echo '<tr>';
        echo '<td>' . number_format($_SESSION['mult_one'][$k]) . '</td>';
        echo '<td>'. ' x ' . '</td>';
        echo '<td>' . number_format($_SESSION['mult_two'][$k]) . '</td>';
        echo '<td>' . ' =   <input data-timer="#timer_' . $k . '" type="text" class="field" name="user_response' . $k . '"' . 'id="u_r' . $k . '" />' . '</td>';
        echo '<td id="timer_' . $k . '">test</td>';
        echo '</tr>';
    }
echo '</table>';
}

Here's the JS:

$(document).ready(function() {
    $('.field').focus(function() {
        var timer_id = $(this).data("timer");
        stopwatch("#" + timer_id);
    });
    $('.field').blur(function() {
        var timer_id = $(this).data("timer");
        stopwatch("#" + timer_id);
    });
});

function stopwatch(container_id) {
  var $container = $(container_id);
  var time_now = new Date();
  var time_started = $container.data("time");
  if (time_started) {
    time_taken = time_now - time_started; // This is in milliseconds
    $container.html(time_taken / 1000 + ' seconds');
  }
  else {
    $container.data("time", time_now);
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文