我正在构建一个聊天系统,我正在使用AJAX技术来异步加载平面.txt文件。
在上面的AJAX技术旁边,我还有一个按钮,可以让您手动启动和停止重新加载平面.txt文件。
当你开始重新加载时,它将每秒/ 1000毫秒执行此操作。
到目前为止一直这么好......当我想用clearInterval函数清除setInterval函数时,问题就来了。它只能运行一次,在我通过启动按钮再次重新加载文档后,我无法阻止它再次使用另一个停止按钮重新加载。
我已经尝试了关于setInterval和clearInterval的几乎所有关于stackoverflow的解决方案,但是它们似乎都没有提供解决方案,或者某些线程只是在没有解决方案的情况下保持打开状态。甚至可以停止并重新启动?然后再次停止等..
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("chatlog").innerHTML = this.responseText;
}
};
xhttp.open("POST", "chatlog.txt", true);
xhttp.send();
}
function scrollWin(x,y) {
window.scrollBy(x,y);
}
var reload = setInterval(loadDoc,1000);
var myStartFunction = function () {
var begin = setInterval(loadDoc,1000);
}
var myStopFunction = function() {
var stop = clearInterval(reload);
}
var elmnt = document.getElementById("chatlog");
function scrollToTop() {
elmnt.scrollIntoView(true); // Top
}
function scrollToBottom() {
elmnt.scrollIntoView(false); // Bottom
}
var autoScroll = setInterval(function () {scrollToBottom()},3000);
function stopAutoScroll() {
clearInterval(autoScroll);
}
BODY
{
margin: 0;
}
.container-one
{
width: 25%;
}
.buttons
{
position: fixed;
border-right: 1px solid #000000;
height: 100%;
z-index: 1;
top: 0px;
background-color: #7F7F7F;
}
.buttons UL
{
list-style-type: none;
margin: 0;
padding: 0;
}
.buttons LI BUTTON
{
width: 100%;
display: block;
border: 1px solid #020202;
padding: 10px;
}
.firstbox
{
margin-left: 240px;
overflow: auto;
margin-top: 115px;
/*[disabled]border:1px solid #000000;*/
}
.chatheader H1
{
text-align: center;
padding: 20px;
margin: 0 auto 0 9%;
border-bottom: 5px solid #000000;
position: fixed;
background-color: #7C7C7C;
top: 0px;
width: 100%;
}
.firstbox P
{
margin-left: auto;
margin-right: auto;
/*[disabled]border:0px solid #000000;*/
/*border-radius: 20px*/
padding: 10%;
background-color: #E0E0E0;
width: 50%;
/*[disabled]height:300px;*/
/*[disabled]overflow:scroll;*/
text-align: center;
}
#chatlog
{
height: auto;
}
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="chatstyle-reload.css">
<meta charset="utf-8" />
<!--<meta http-equiv="refresh" content="5" > -->
<title>Test page for requesting a webpage with the AJAX technique!</title>
</head>
<body>
<div class="container-one">
<div class="buttons">
<ul>
<li><button type="button" onclick="loadDoc()">Request the chatlog</button></li>
<li><button type="button" id="reloadBtn" onclick="myStartFunction()">Start updating the chatlog</button></li>
<li><button type="button" id="stopBtn" onclick="myStopFunction()">Stop reloading the chatlog</button></li>
<li><button type="button" onclick="document.getElementById('chatlog').innerHTML = 'Chatlog is hidden'">Hide chatlog</button></li>
<li><button type="button" onclick="scrollWin(0,-50)">Go to top of page</button></li>
<li><button type="button" onclick="scrollWin(0,200)">Go to bottom of page</button></li>
<li><button type="button" onclick="scrollToTop()">Scroll to the top of the element</button></li>
<li><button type="button" onclick="scrollToBottom()">Scroll to the bottom of the element</button></li>
<li><button type="button" onclick="stopAutoScroll()">Stop autoscroll</button></li>
<li><button type="button"> <a href="http://www.checkandtest.nl">Go back => to checkandtest.nl</a></button></li>
</ul>
</div>
</div>
<div class="chatheader">
<h1>Display the current chatlog in real-time</h1>
</div>
<div class="firstbox">
<p id="chatlog"></p>
</div>
<script src="functions.js"> </script>
</body>
</html>
你的问题在这里:
var reload = setInterval(loadDoc,1000);
var myStartFunction = function () {
var begin = setInterval(loadDoc,1000);
}
var myStopFunction = function() {
var stop = clearInterval(reload);
}
你通过setInterval
创建一个interal并将其存储到reload
中,可以正确停止,但是当你通过myStartFunction
再次启动时,你将它存储到一个名为begin
的本地未使用变量中,并且在停止时你打算停止具有reload
id的区间,已经停止了。相反,你需要改变myStartFunction
:
var myStartFunction = function () {
myStopFunction(); //Stop any previous unstopped interval
reload = setInterval(loadDoc,1000);
}
编辑
在这里,我详细说明了在上一次编辑此答案之前我们遇到的问题。在上次编辑之前,我们有var reload = setInterval(loadDoc,1000);在myStartFunction中,它创建一个名为reload的局部变量,但是这个局部变量“遮蔽”外部变量reload,因此,我们设置了局部变量的值,我们期望将值赋给全局变量。这是我的错字,但解释它是很好的。让我给你举个例子:
var myVariable = 1;
function foo() {
var myVariable = 2;
}
foo();
console.log(myVariable); //1
如您所见,我们有两个名为myVariable的变量。在函数的范围内,我们创建了一个具有相同名称的变量,并赋值为2.即使我们调用该函数,外部变量也不会让步。现在,让我们删除函数内的var关键字:
var myVariable = 1;
function foo() {
myVariable = 2;
}
foo();
console.log(myVariable); //2
我找到了一个临时解决方案。我现在可以开始和停止重新加载文档..但是,当我通过buttonclick两次调用'myStartFunction'时,我无法再使用'myStopFunction'按钮点击它。
所以我解决了1个问题,即使我不明白我做了什么..并创造了另一个。
问题似乎是'var'关键字..我从'reload'变量中删除了'var'。我还在'myStartFunction'代码块中添加了一个'return reload'语句。
我不明白它为什么会起作用,我发现我必须这样做才真的很奇怪..但我确实在另一个网站上发现了一些东西,当你在javascript中声明一个没有'var'关键字的变量时变量成为全局变量。我怀疑它与范围或setInterval创建的不可访问的变量有关。
请记住,'setInterval'函数的每个被调用实例都会创建一个新的id,并且我们需要一种方法来从每个实例访问新创建的'setInterval'id,以便使用'clearInterval'来停止它。
所以我们从@Lajos Arpad的建议中得出结论:
var myStartFunction = function () {
myStopFunction(); //Stop any previous unstopped interval
var reload = setInterval(loadDoc,1000);
}
对此:
var myStartFunction = function () {
reload = setInterval(loadDoc,1000);
return reload;
}
var myStopFunction = function () {
console.log("Stop reloading the document " + reload);
clearInterval(reload);
}
reload = setInterval(loadDoc,1000);
document.getElementById("reloadBtn").addEventListener("click", myStartFunction);
document.getElementById("stopBtn").addEventListener("click", myStopFunction);
loadDoc();
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("chatlog").innerHTML = this.responseText;
}
};
xhttp.open("POST", "chatlog.txt", true);
xhttp.send();
}