Javascript Safari未运行confirm()方法之前的行
这实际上是书的头一个JavaScript ch05中的一个例子。除了Safari,我对Firefox中的代码没有问题,我也不确定问题出在哪里Javascript Safari未运行confirm()方法之前的行,javascript,html,safari,Javascript,Html,Safari,这实际上是书的头一个JavaScript ch05中的一个例子。除了Safari,我对Firefox中的代码没有问题,我也不确定问题出在哪里 <html> <head> <title>Mandango - The Macho Movie Ticket Finder</title> <script type="text/javascript"> var seats = [ false,
<html>
<head>
<title>Mandango - The Macho Movie Ticket Finder</title>
<script type="text/javascript">
var seats = [ false, true, false, true, true, true, false, true, false ];
var selSeat = -1;
function initSeats() {
// Initialize the appearance of all seats
for (var i = 0; i < seats.length; i++) {
if (seats[i]) {
// Set the seat to available
document.getElementById("seat" + i).src = "seat_avail.png";
document.getElementById("seat" + i).alt = "Available seat";
}
else {
// Set the seat to unavailable
document.getElementById("seat" + i).src = "seat_unavail.png";
document.getElementById("seat" + i).alt = "Unavailable seat";
}
}
}
function findSeat() {
// If seat is already selected, reinitialize all seats to clear them
if (selSeat >= 0) {
selSeat = -1;
initSeats();
}
// Search through all the seats for availability
for (var i = 0; i < seats.length; i++) {
// See if the current seat is available
if (seats[i]) {
// Set the seat selection and update the appearance of the seat
selSeat = i;
document.getElementById("seat" + i).src = "seat_select.png";
document.getElementById("seat" + i).alt = "Your seat";
// Prompt the user to accept the seat
var accept = confirm("Seat " + (i + 1) + " is available. Accept?");
if (accept) {
// The user accepted the seat, so we're done
break;
}
else {
// The user rejected the seat, so clear the seat selection and keep looking
selSeat = -1;
document.getElementById("seat" + i).src = "seat_avail.png";
document.getElementById("seat" + i).alt = "Available seat";
}
}
}
}
</script>
</head>
<body onload="initSeats();">
<div style="margin-top:75px; text-align:center">
<img id="seat0" src="" alt="" />
<img id="seat1" src="" alt="" />
<img id="seat2" src="" alt="" />
<img id="seat3" src="" alt="" />
<img id="seat4" src="" alt="" />
<img id="seat5" src="" alt="" />
<img id="seat6" src="" alt="" />
<img id="seat7" src="" alt="" />
<img id="seat8" src="" alt="" /><br />
<input type="button" id="findseat" value="Find Seat" onclick="findSeat();" />
</div>
</body>
</html>
曼丹戈-男子汉电影票务发现者
var seats=[假,真,假,真,真,真,假,真,假];
var selSeat=-1;
函数initSeats(){
//初始化所有座椅的外观
对于(变量i=0;i=0){
selSeat=-1;
initSeats();
}
//在所有座位中搜索是否有空位
对于(变量i=0;i
它假设在座椅中循环寻找可用的(真实的)座椅,更新座椅图像并通过确认方法询问用户
问题在于findSeat函数:
它在Firefox上运行得非常完美,但当我在Safari(9.1版)中运行它时,在我单击确认框中的“确定”之前,座椅图像不会更新。i、 e.在确认方法返回True之前,以下代码不会运行
document.getElementById(“seat”+i).src=“seat\u select.png”
document.getElementById(“座椅”+i).alt=“您的座椅”
我想这就是确认方法的问题。有人能帮忙吗?谢谢
seat_select.png
seat_avail.png
seat_unavail.png
浏览器上的JavaScript使用单个UI线程1运行,该线程(取决于浏览器体系结构)除了运行JavaScript之外,还可以执行其他工作,通常是与UI相关的任务,如更新图像
confirm
方法(及其近亲alert
)使该线程在许多浏览器上突然停止,阻止其执行任何操作,直到/除非用户关闭该对话框
您引用的代码假设座椅图像将与分配到src
的任务同步更新(这不是一个安全的假设,尤其是因为它可能需要下载),或者在显示确认
对话框时更新(这不是一个安全的假设)
相反,代码应该在img
元素上使用load
事件回调,类似这样(基本上未测试),请参见注释:
function findSeat() {
var seatDisplay;
// If seat is already selected, reinitialize all seats to clear them
if (selSeat >= 0) {
selSeat = -1;
initSeats();
}
// Find an available seat
var availableSeat = null;
seats.some(function(seat, index) {
if (seat) {
availableSeat = seat;
selSeat = index;
return true; // Stop looping
}
});
if (availableSeat) {
// Set the seat selection and update the appearance of the seat
var seatDisplay = document.getElementById("seat" + selSeat);
seatDisplay.src = "";
seatDisplay.addEventListener("load", seatReady, false);
seatdisplay.src = "seat_select.png";
seatdisplay.alt = "Your seat";
}
function seatReady() {
// Remove this handler
seatDisplay.removeEventListener("load", seatReady, false);
// Prompt the user to accept the seat
var accept = confirm("Seat " + (selSeat + 1) + " is available. Accept?");
if (accept) {
// The user accepted the seat, so we're done
}
else {
// The user rejected the seat, so clear the seat selection and keep looking
selSeat = -1;
seatDisplay.src = "seat_avail.png";
seatDisplay.alt = "Available seat";
}
}
}
他们可能没有这样做,因为他们想避免书中这个阶段的复杂性,但不幸的是,他们显然没有在不同的浏览器上进行充分的测试,并且不知道可能的竞争条件
1“浏览器上的JavaScript使用单UI线程运行…”但并不像人们经常说的那样是单线程的。只有一个UI线程,但是您可以使用任意多的其他线程。Safari中似乎存在一个错误,在前面的代码执行之前,确认方法会触发。一种解决方案是在setTimeout回调函数中运行confirm 例如
只是FWIW,对于一本应该教授JavaScript的书来说,不能说这是非常令人印象深刻的代码。我想在这本书之后我还需要另一本参考书。谢谢你的提示。
var accept;
function doConfirm() {
accept = confirm("Seat " + (i + 1) + " is available. Accept?");
}
// run the confirm after 200ms
window.setTimeout(doConfirm(), 200);