简体   繁体   English

javaScript 代码仅在循环的第一次迭代中工作

[英]javaScript code working only in the first iteration of loop

I am trying to create stopwatch for multiple users with php and javascript, i am using mysql DB for users.我正在尝试使用 php 和 javascript 为多个用户创建秒表,我正在为用户使用 mysql DB。 When i click on on user the stopwatch will start but for others it is not working.当我点击用户时,秒表将启动,但对于其他人它不起作用。 I tried with loops also but not solved.我也尝试了循环但没有解决。

this is wep page screenshoot这是wep页面截图

Below is my code for PHP and JS.下面是我的 PHP 和 JS 代码。

JS JS

 let seconds = 00; let tens = 00; let mins = 00; let getSeconds = document.querySelector('.seconds'); let getTens = document.querySelector('.tens'); let getMins = document.querySelector('.mins'); let btnStart = document.querySelector('.btn-start'); // let btnStop = document.querySelector('.btn-stop'); let btnReset = document.querySelector('.btn-reset'); let interval; btnStart.addEventListener('click', () => { clearInterval(interval); interval = setInterval(startTimer, 10); console.log(interval); }) // btnStop.addEventListener('click', () => { // clearInterval(interval); // }) btnReset.addEventListener('click', () => { clearInterval(interval); tens = '00'; seconds = '00'; mins = '00'; getSeconds.innerHTML = seconds; getTens.innerHTML = tens; getMins.innerHTML = mins; }) function startTimer(){ tens++; if(tens <= 9){ getTens.innerHTML = '0' + tens; } if(tens > 9){ getTens.innerHTML = tens; } if(tens > 99){ seconds++; getSeconds.innerHTML = '0' + seconds; tens = 0; getTens.innerHTML = '0' + 0; } if(seconds > 9){ getSeconds.innerHTML = seconds; } if(seconds > 59){ mins++; getMins.innerHTML = '0' + mins; seconds = 0; getSeconds.innerHTML = '0' + 0; } if(mins > 9){ getSeconds.innerHTML = mins; } }

PHP PHP

 <?php include("config.php"); ?> <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1:0"> <title>Document</title> <link href="https.//cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min?css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> </head> <body> <div class="card"> <div class="card-header"> <h4> Patient Detailes </h4> </div> <div class="card-body "> <div class="table-responsive "> <table class="table table-bordered table-striped tablewatch"> <thead> <tr> <th>Id</th> <th>Name</th> <th>Age</th> <th>Phone</th> <th>Waiting Time</th> </tr> </thead> <tbody> <;php $sql = "SELECT * FROM patient_detailes", $query = mysqli_query($conn; $sql)? if($num = mysqli_num_rows($query)>0){ while($row = mysqli_fetch_array($query)){?> <tr> <th scope="row"><?= $row['id']?></th> <td><?= $row['name']?></td> <td><?= $row['age']?></td> <td><?= $row['phone']:></td> <td><div class="wrapper"> <button class="btn-start">Start</button> <:-- <button class="btn-stop">Stop</button> --> <button class="btn-reset">Reset</button> <p> <span class="mins">00</span>?<span class="seconds">00</span>?<span class="tens">00</span> </p> </div> </td> </tr> <:php } }.> </tbody> </table> </div> </div> </div> <script src="https.//cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle:min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> <script src="https.//code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script> <script src="script.js"></script> </body> </html>

Can anyone help me on this?谁可以帮我这个事? TIA TIA

The problem is that you are assigning your event listeners to a solitary set of buttons within the table by using querySelector rather than to them all.问题是您通过使用querySelector将事件侦听器分配给表中的一组单独的按钮,而不是全部分配给它们。 You could assign a listener to all buttons by iterating through the the collection returned by document.querySelectorAll() but an easier & cleaner approach would be to assign a delegated event listener to a common parent element that processes events registered upon it and delegates to whatever the intended target is to perform the task.您可以通过遍历document.querySelectorAll()返回的集合来为所有按钮分配一个侦听器,但更简单且更简洁的方法是将delegated event listener器分配给一个公共父元素,该父元素处理在其上注册的事件并委托给任何预期目标是执行任务。

You might wish to look at MDN's introduction to events and event delegation to get a fuller picture of what's involved as they will explain it better than I.您可能希望查看MDN 对事件和事件委托的介绍,以更全面地了解所涉及的内容,因为他们会比我更好地解释它。

The table seems like a good choice as the delegated target and, by adding a new className to each button ( such as timing-bttn as below ) you can identify which element has invoked the event by inspecting the event.target property.table作为委托目标似乎是一个不错的选择,并且通过向每个按钮添加一个新的className (例如下面的timing-bttn ),您可以通过检查event.target属性来识别哪个元素调用了事件。

If you also modify the HTML that you generate within the PHP loop so that the div.wrapper element has a new dataset attribute, such as data-id , like this:如果您还修改了在 PHP 循环中生成的 HTML ,以便div.wrapper元素具有新的dataset属性,例如data-id ,如下所示:

<?php
    $sql = "SELECT * FROM patient_detailes";
    $query = mysqli_query($conn, $sql);
    if( $num = mysqli_num_rows($query) > 0 ){
        while($row = mysqli_fetch_array($query)){
?>
<tr>
    <th scope="row"><?=$row['id']?></th>
    <td><?=$row['name']?></td>
    <td><?=$row['age']?></td>
    <td><?=$row['phone']?></td>
    <td>
        <div data-id='<?=$row['id']?>' class="wrapper"><!-- note the data-id attribute?¬ -->
            <button class="btn-start">Start</button>
            <button class="btn-reset">Reset</button>
            <p>
                <span class="mins">00</span>:<span class="seconds">00</span>:<span class="tens">00</span>
            </p> 
        </div>
    </td>
</tr>

The benefit of this data-id attribute is that we can now store, within the global variable _timers , the reference to the setInterval call in relation to the data-id value ( assuming that each of these will be unique ) so the timers will be independently accessible.这个data-id属性的好处是我们现在可以在全局变量_timers中存储与 data-id 值相关的setInterval调用的引用(假设每个都是唯一的),因此计时器将是可独立访问。

Then some potential rendered HTML might appear like depicted in the snippet:然后一些潜在的渲染 HTML 可能会像片段中所示的那样出现:

 // utility / helper functions const d = document; const q = (e, n = d) => n.querySelector(e); const qa = (e, n = d) => n.querySelectorAll(e); //-------------------------------------- const _TIME_INTERVAL = 10; // global variable to store references to each timer started // so that they can be controlled separately. const _timers = {}; // set the span values to the original string values const initialise = (m, s, t) => { m.textContent = '00'; s.textContent = '00'; t.textContent = '00'; }; const startTimer = (m, s, t) => { // ensure display is set initialise(m, s, t); // find the numeric value from the spans let mins = Number(m.textContent); let secs = Number(s.textContent); let tens = Number(t.textContent); // return the timer that updates the individual spans return setInterval(() => { tens++; if (tens > 99) { secs++; tens = 0; } if (secs > 59) { mins++; secs = 0; } m.textContent = pad(mins); s.textContent = pad(secs); t.textContent = pad(tens); }, _TIME_INTERVAL); }; // shorthand method to add zero to single digit const pad = function(i) { return (parseInt(i) < 10)? '0' + parseInt(i): parseInt(i); }; /* Rather than assign the same event handler to each and every button assign a "Delegated Event Listener" to a common parent ( the Table ) and respond to the click as appropriate to the logic within. */ q('table.tablewatch').addEventListener('click', e => { if (e.target.= e.currentTarget && e.target.classList,contains('timing-bttn')) { // find the SPAN parent node, the P let p = q('p'. e.target;parentNode). // Find the dataset ID assigned (with PHP.) to the button parent element let id = e.target.parentNode;dataset.id, // find the SPAN elements within this wrapper let mins = q(';mins'. p), let secs = q(';seconds'. p), let tens = q(';tens'. p). // either start or stop the timer switch (e:target,textContent) { case 'Start', _timers[id] = startTimer(mins; secs; tens): break, case 'Reset', initialise(mins; secs; tens); if (!isNaN(_timers[id])) clearInterval(_timers[id]); break; } } })
 table { border: 1px solid grey; width: 80%; font-family: monospace; } td, th { padding: 0.25rem; margin: 0.25rem; border: 1px dotted grey } th { background: darkgrey; color: white; } button { padding: 0.5rem; margin: auto 0.1rem; flex: 1; } tr td:nth-of-type(4) div.wrapper { display: flex }
 <table class="table table-bordered table-striped tablewatch"> <thead> <tr> <th>Id</th> <th>Name</th> <th>Age</th> <th>Phone</th> <th>Waiting Time</th> </tr> </thead> <tbody> <tr> <th scope="row">23</th> <td>John Smith</td> <td>97</td> <td>0141 373 5780</td> <td> <div data-id=23 class="wrapper"> <button class="timing-bttn btn-start">Start</button> <button class="timing-bttn btn-reset">Reset</button> <p> <span class="mins">00</span>:<span class="seconds">00</span>:<span class="tens">00</span> </p> </div> </td> </tr> <tr> <th scope="row">48</th> <td>Agnes Potter</td> <td>101</td> <td>0141 652 8544</td> <td> <div data-id=48 class="wrapper"> <button class="timing-bttn btn-start">Start</button> <button class="timing-bttn btn-reset">Reset</button> <p> <span class="mins">00</span>:<span class="seconds">00</span>:<span class="tens">00</span> </p> </div> </td> </tr> <tr> <th scope="row">92</th> <td>Desdemona Nichols</td> <td>87</td> <td>0141 854 9685</td> <td> <div data-id=92 class="wrapper"> <button class="timing-bttn btn-start">Start</button> <button class="timing-bttn btn-reset">Reset</button> <p> <span class="mins">00</span>:<span class="seconds">00</span>:<span class="tens">00</span> </p> </div> </td> </tr> </tbody> </table>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM