这里是 JavaScript 初学者 :) 摘要: 如何使事件监听器依赖于 AJAX 调用的结果?如果监听器是在调用之后添加的,那么它将在每个调用之后添加,从而累积监听器。如果我在调用之前执行此操作,如何将调用结果传递给它?监听器似乎不接受用户定义的参数。
详细信息:我正在尝试编写一个网络照片查看器,其中将在照片上标记面孔。要在照片之间切换,我想使用 AJAX。我的PHP脚本以JSON字符串的形式返回图片文件的名称和面的坐标(x,y,半径),例如
{"filename":"im1.jpg","faces":[{"x":129,"y":260,"radius":40},{"x":232,"y":297,"radius":40}]}
当鼠标悬停在照片上时,我想根据面孔
在 Canvas 上绘制圆圈。因此,我为 mouseover
事件创建了一个监听器。问题是,如果我在 AJAX 调用后添加监听器, Canvas 将获得多个监听器并继续从之前的照片中绘制圆圈。所以看起来处理程序需要提前定义。但后来我很难将 AJAX 响应传递给它。我怎样才能实现它?
到目前为止,我的 HTML 代码如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<canvas id="canvas" width="100" height="600"
style="background-size: 100% 100%; border: 1px solid #FF0000;"></canvas>
<script>
var image = new Image();
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.addEventListener('mouseout', function(evt) {
context.clearRect(0, 0, canvas.width, canvas.height);
console.log("Canvas cleared");
}, false);
function loadXMLDoc() {
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var ajaxData = JSON.parse(xmlhttp.responseText);
image.src = ajaxData.filename;
image.onload = function() {
canvas.width = Math.round(canvas.height / image.height * image.width);
canvas.style.backgroundImage = "url('" + image.src + "')";
}
var faces = ajaxData.faces;
canvas.addEventListener('mouseover', function(evt) {
console.log("Canvas entered");
console.log("Faces to mark: " + faces.length);
for (i = 0; i < faces.length; i++) {
context.beginPath();
context.arc(faces[i].x, faces[i].y,
faces[i].radius, 0, 2 * Math.PI);
context.strokeStyle = "#00BBBB";
context.lineWidth = 1;
context.stroke();
}
}, false);
}
}
xmlhttp.open("GET", "get_data.php", true);
xmlhttp.send();
}
</script>
<button type="button" onclick="loadXMLDoc()">Change Content</button>
</body>
</html>
最佳答案
您可以remove the old listener在添加新的之前。但更好的方法是将数据保存到事件监听器外部的变量中,该变量会在每次 AJAX 响应后更新。那么监听器调用的函数根本不需要改变,它只是引用带有你的面部数据的变量。
编辑
您可以在脚本顶部添加另一个变量:var faces;
。脚本的其余部分将可以访问它,就像其他变量一样。您最初不需要为其分配值。现在将您的 mouseover
监听器与 mouseout
监听器置于同一级别。当您从服务器获取数据时,只需将其分配给faces:faces = ajaxData.faces;
(这里不要使用var
,否则它将把faces定义为回调中的局部变量)。现在上面定义的 faces 变量将具有该数据,并且监听器将可以访问它。每次进行 AJAX 调用时,它都会用新的面孔覆盖旧的面孔。您可能需要在 mouseover
监听器中添加检查,以确保变量具有数据。您可以这样检查:
if (typeof faces == 'object'){
// your for loop can go here
}
在 AJAX 回调设置 faces 的值之前,typeof faces
将等于 'undefined'
。
在您掌握语言如何处理作用域之前,JavaScript 将会令人困惑。 Check this out作为一个好的起点。
关于javascript - 使 JavaScript 事件处理程序依赖于 AJAX 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26131526/