使用 onclick 事件调用 JQuery 函数在 Php 下载计数器上未按预期工作
Calling JQuery function using onclick event not working as expected on Php download counter
我有一个 Php
script 可以计算使用 Php
和 JQuery
下载文件的次数。我有一个函数 getStatus()
每秒调用一个文件 Php
并消耗大量带宽。然后我尝试仅在用户单击下载 link 时调用 getStatus()
,但即使我没有收到错误,也没有按预期工作,计数器(javascript
部分)未更新实时。只有在 getStatus()
之后放置 alert()
才能正常工作。
index.php
<?php include($_SERVER["DOCUMENT_ROOT"] . "/php/static_download.php"); ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Download Page</title>
<script src="jsc/jquery.min.js"></script>
<script src="jsc/download.js"></script>
<link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
<div class="mainbox">
<div class="box1">
<span class="title">Download</span>
</div>
<div class="cleardiv"></div>
<div class="sbar"></div>
<div class="cleardiv"></div>
<div class="box2">
<span class="row">File: <a href="files/exampleA.zip" class="link">exampleA.zip</a> downloaded <span id="item1"><?php echo $item['item1']; ?></span> times</span><br />
<span class="row">File: <a href="files/exampleB.zip" class="link">exampleB.zip</a> downloaded <span id="item2"><?php echo $item['item2']; ?></span> times</span><br />
<span class="row">File: <a href="test/test.zip" class="link">test.zip</a> this file will not be counted</span><br />
</div>
<div class="cleardiv"></div>
</div>
</body>
</html>
call_download.php
<?php
$item['item1'] = get_download_count('exampleA.zip');
$item['item2'] = get_download_count('exampleB.zip');
if (!headers_sent()) {
header('Content-type: application/json; charset=utf-8');
}
echo json_encode($item);
?>
download.js
$(function() {
getStatus();
});
function getStatus() {
$.getJSON('/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
});
setTimeout("getStatus()",1000);
}
如您所见,getStatus()
函数每隔一秒调用一次,因此我尝试按如下方式修改 download.js:
download.js
$(document).ready(function() {
$(document).on('click','.link',function(event) {
getStatus();
alert("Thanks for downloading my files!");
});
});
function getStatus() {
$.getJSON('/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
});
}
由于某些我无法理解的原因,在 getStatus()
之后附加 alert()
会使计数器工作...如果我评论 alert()
停止工作。
PS:我测试了 getStatus() 并且令我惊讶的是我发现了一件奇怪的事情...
$(document).ready(function() {
$(document).on('click','.link',function(event) {
getStatus();
alert("Thanks for downloading my files!");
});
});
function getStatus() {
$.getJSON('/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
alert("success");
}).done(function(getStatus) {
alert("success");
}).fail(function(getStatus) {
alert("error");
}).always(function(getStatus) {
alert("complete");
});
}
与 alert("Thanks for downloading my files!");
returns success
,注释 //alert("Thanks for downloading my files!");
returns error
... 仅适用于 alert()
。 ...计数器对我来说不是实时更新的...
注意事项
如您所见,由于在点击事件中添加了 setTimeout()
函数,现在仅当用户单击 link 时才会调用 getStatus()
函数。现在按预期工作。
download.js
$(document).ready(function() {
$.ajaxSetup({cache: false});
// $.ajaxSetup({async: false});
$(document).on('click','.link',function(event) {
setTimeout("getStatus()",1000);
});
});
function getStatus() {
$.getJSON('/test/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
});
}
感谢您花时间帮助我!
这可能是因为它触发了link事件,需要先保持
尝试:
$(document).on('click','.link',function(event, gotoUrl) {
if(!gotoUrl){
event.preventDefault();
getStatus(); // <-- maybe you should have a callback function to make sure you get response and only then trigger the click event
$(event.target).click(event, true);
return false;
}
});
为什么会出现这种情况是因为您可能误解了 Js 中的异步性作为 adeneo 提到的。所以请研究那个领域。阅读此 Async
你不能在Js中做一个真正自定义的异步函数。您最终将不得不利用 Js 中原生提供的技术,例如:
- 设置间隔
- 设置超时
- 等..等..
为了快速解决问题,我可以给你这个。
$(document).ready(function() {
$(document).on('click','.link',function(event) {
$.getJSON('/test/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
alert("success");
}).done(function(getStatus) {
alert("success");
}).fail(function(getStatus) {
alert("error");
}).always(function(getStatus) {
alert("complete");
});
});
});
根据我在评论中提出的后续问题以及您对 call_download.php
定义的 link,您的问题是您在下载计数实际增加之前获取了下载计数。
使请求同步 (async: false
) 不会有任何影响(除了恶化用户体验),这只会让后续代码等待 $.getJSON()
完成,但是你有没有后续代码。
除了处理时间戳之外,call_download.php
没有简单可靠的方法来知道另一个请求(增加计数器)是否完成。
最简单的选项是:
假设数据库中的计数递增总是需要一定的时间: 延迟 $.getJSON()
with setTimeout()
与(通常)将计数写入数据库所需的时间一样多,有一些余量。
假设call_download.php
总是在数据库中的计数递增之前从数据库中读取数据:从[=中递增结果12=] 与 $('#item1').html(data.item1 + 1);
.
根据 Iceburg 和 Samuel Lindblom 的回答,我最终编写了一个仅在用户单击要下载的文件时才使用 setTimeout 的函数,并且不再使用 $.ajaxSetup({async: false});
,该函数在未来版本中已弃用。因此可以节省大量带宽!全部!谢谢!
$(document).ready(function() {
$.ajaxSetup({cache: false});
// $.ajaxSetup({async: false});
$(document).on('click','.link',function(event) {
setTimeout("getStatus()",1000);
});
});
function getStatus() {
$.getJSON('/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
});
}
我有一个 Php
script 可以计算使用 Php
和 JQuery
下载文件的次数。我有一个函数 getStatus()
每秒调用一个文件 Php
并消耗大量带宽。然后我尝试仅在用户单击下载 link 时调用 getStatus()
,但即使我没有收到错误,也没有按预期工作,计数器(javascript
部分)未更新实时。只有在 getStatus()
之后放置 alert()
才能正常工作。
index.php
<?php include($_SERVER["DOCUMENT_ROOT"] . "/php/static_download.php"); ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Download Page</title>
<script src="jsc/jquery.min.js"></script>
<script src="jsc/download.js"></script>
<link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
<div class="mainbox">
<div class="box1">
<span class="title">Download</span>
</div>
<div class="cleardiv"></div>
<div class="sbar"></div>
<div class="cleardiv"></div>
<div class="box2">
<span class="row">File: <a href="files/exampleA.zip" class="link">exampleA.zip</a> downloaded <span id="item1"><?php echo $item['item1']; ?></span> times</span><br />
<span class="row">File: <a href="files/exampleB.zip" class="link">exampleB.zip</a> downloaded <span id="item2"><?php echo $item['item2']; ?></span> times</span><br />
<span class="row">File: <a href="test/test.zip" class="link">test.zip</a> this file will not be counted</span><br />
</div>
<div class="cleardiv"></div>
</div>
</body>
</html>
call_download.php
<?php
$item['item1'] = get_download_count('exampleA.zip');
$item['item2'] = get_download_count('exampleB.zip');
if (!headers_sent()) {
header('Content-type: application/json; charset=utf-8');
}
echo json_encode($item);
?>
download.js
$(function() {
getStatus();
});
function getStatus() {
$.getJSON('/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
});
setTimeout("getStatus()",1000);
}
如您所见,getStatus()
函数每隔一秒调用一次,因此我尝试按如下方式修改 download.js:
download.js
$(document).ready(function() {
$(document).on('click','.link',function(event) {
getStatus();
alert("Thanks for downloading my files!");
});
});
function getStatus() {
$.getJSON('/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
});
}
由于某些我无法理解的原因,在 getStatus()
之后附加 alert()
会使计数器工作...如果我评论 alert()
停止工作。
PS:我测试了 getStatus() 并且令我惊讶的是我发现了一件奇怪的事情...
$(document).ready(function() {
$(document).on('click','.link',function(event) {
getStatus();
alert("Thanks for downloading my files!");
});
});
function getStatus() {
$.getJSON('/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
alert("success");
}).done(function(getStatus) {
alert("success");
}).fail(function(getStatus) {
alert("error");
}).always(function(getStatus) {
alert("complete");
});
}
与 alert("Thanks for downloading my files!");
returns success
,注释 //alert("Thanks for downloading my files!");
returns error
... 仅适用于 alert()
。 ...计数器对我来说不是实时更新的...
注意事项
如您所见,由于在点击事件中添加了 setTimeout()
函数,现在仅当用户单击 link 时才会调用 getStatus()
函数。现在按预期工作。
download.js
$(document).ready(function() {
$.ajaxSetup({cache: false});
// $.ajaxSetup({async: false});
$(document).on('click','.link',function(event) {
setTimeout("getStatus()",1000);
});
});
function getStatus() {
$.getJSON('/test/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
});
}
感谢您花时间帮助我!
这可能是因为它触发了link事件,需要先保持
尝试:
$(document).on('click','.link',function(event, gotoUrl) {
if(!gotoUrl){
event.preventDefault();
getStatus(); // <-- maybe you should have a callback function to make sure you get response and only then trigger the click event
$(event.target).click(event, true);
return false;
}
});
为什么会出现这种情况是因为您可能误解了 Js 中的异步性作为 adeneo 提到的。所以请研究那个领域。阅读此 Async
你不能在Js中做一个真正自定义的异步函数。您最终将不得不利用 Js 中原生提供的技术,例如:
- 设置间隔
- 设置超时
- 等..等..
为了快速解决问题,我可以给你这个。
$(document).ready(function() {
$(document).on('click','.link',function(event) {
$.getJSON('/test/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
alert("success");
}).done(function(getStatus) {
alert("success");
}).fail(function(getStatus) {
alert("error");
}).always(function(getStatus) {
alert("complete");
});
});
});
根据我在评论中提出的后续问题以及您对 call_download.php
定义的 link,您的问题是您在下载计数实际增加之前获取了下载计数。
使请求同步 (async: false
) 不会有任何影响(除了恶化用户体验),这只会让后续代码等待 $.getJSON()
完成,但是你有没有后续代码。
除了处理时间戳之外,call_download.php
没有简单可靠的方法来知道另一个请求(增加计数器)是否完成。
最简单的选项是:
假设数据库中的计数递增总是需要一定的时间: 延迟
$.getJSON()
withsetTimeout()
与(通常)将计数写入数据库所需的时间一样多,有一些余量。假设
call_download.php
总是在数据库中的计数递增之前从数据库中读取数据:从[=中递增结果12=] 与$('#item1').html(data.item1 + 1);
.
根据 Iceburg 和 Samuel Lindblom 的回答,我最终编写了一个仅在用户单击要下载的文件时才使用 setTimeout 的函数,并且不再使用 $.ajaxSetup({async: false});
,该函数在未来版本中已弃用。因此可以节省大量带宽!全部!谢谢!
$(document).ready(function() {
$.ajaxSetup({cache: false});
// $.ajaxSetup({async: false});
$(document).on('click','.link',function(event) {
setTimeout("getStatus()",1000);
});
});
function getStatus() {
$.getJSON('/php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
});
}