2011-09-08 38 views
15

Trong hầu hết các trình duyệt (bao gồm các phiên bản cũ hơn của Safari), hàm Javascript prompt trả về null khi người dùng nhấp vào "Hủy" và chuỗi trống nếu người dùng nhấp vào "Ok" hộp văn bản. Nhưng trong Safari 5.1, nó trả về chuỗi rỗng cho cả hai trường hợp.Chức năng dấu nhắc Safari 5.1() và hủy

Tôi đã sử dụng tính năng "báo cáo lỗi" của Safari để báo cáo cho Apple, nhưng ai biết khi nào họ thậm chí có thể thừa nhận nó ít khắc phục được nó. Có ai có một workaround?

Trả lời

2

Tôi đã tìm cách giải quyết thực sự, vì Safari đã thêm hỗ trợ cho showModalDialog() trong 5.1. Awfully thuận tiện, đó.

Đầu tiên, tạo một tập tin với nội dung này:

<html> 
<head> 
<title>Prompt</title> 
<script type="text/javascript"> 
function a(){ 
     if(window.dialogArguments.length > 0) 
       document.getElementById('a').textContent = window.dialogArguments[0]+'\n\n'; 
     if(window.dialogArguments.length > 1) 
       document.getElementById('b').value = window.dialogArguments[1]; 
     document.getElementById('b').focus(); 
} 

function s(b){ 
     window.returnValue=b?document.getElementById('b').value:null; 
     window.close(); 
} 

function kp(e){ 
     if(!e.DOM_VK_ENTER) e.DOM_VK_ENTER=13; 
     if(!e.DOM_VK_RETURN) e.DOM_VK_RETURN=13; 
     if(!e.DOM_VK_ESCAPE) e.DOM_VK_ESCAPE=27; 

     switch(e.keyCode){ 
      case e.DOM_VK_ENTER: 
      case e.DOM_VK_RETURN: 
      if(e.preventDefault) e.preventDefault(); 
      if(e.stopPropagation) e.stopPropagation(); 
      e.returnValue = false; 
      e.cancelBubble = true; 
      s(1); 
      return false; 

      case e.DOM_VK_ESCAPE: 
      if(e.preventDefault) e.preventDefault(); 
      if(e.stopPropagation) e.stopPropagation(); 
      e.returnValue = false; 
      e.cancelBubble = true; 
      s(0); 
      return false; 

      default: 
      return true; 
     } 
} 
</script> 
<body style="text-align:center;white-space:pre-wrap" onload="a()"> 
<span id="a"></span> 
<input type="text" id="b" onkeydown="return kp(event)" /><input type="button" value="Ok" onclick="s(1)" /><input type="button" value="Cancel" onclick="s(0)" /> 
</body> 
</html> 

Sau đó, cho các phiên bản bị hỏng của Safari (có vẻ là không có cách nào để tính năng phát hiện điều này mà không nảy lên một dấu nhắc và yêu cầu người dùng nhấn "Hủy", vì vậy có thể bạn sẽ phải làm một tấm séc User-Agent), thực hiện javascript sau đây để thay thế window.prompt:

(function(){ 
     if(window.console && window.console.log) 
       window.console.log('Applying bugfix for Safari 5.1\'s prompt()'); 
     var oldprompt = window.prompt; 
     window.prompt = function() { 
       return showModalDialog(location.protocol+'//'+location.host+'/js/safari-5.1-bugfix.html', arguments); 
     }; 
     window.prompt.$orig = oldprompt; 
})(); 

Tất nhiên, thay đổi đường dẫn /js/safari-5.1-bugfix.html để đúng đường dẫn đến tạo trên Tệp HTML trên máy chủ của bạn. Rất tiếc, chúng tôi không thể sử dụng số data: URI vì Safari dường như có lỗi lỗi khác khi mất window.dialogArguments và bỏ qua window.returnValue cho các hộp thoại có data: URI.

Sau đó, bạn có thể sử dụng prompt() như bình thường.

+0

Rất tốt, cảm ơn bạn! – Bibou

-1

Chắc chắn, hai thực tế.

Đầu tiên là hiển nhiên, thiết kế lại hệ thống của bạn để chuỗi rỗng không phải là phản hồi hợp lệ. Hãy suy nghĩ về nó, khi trong một cuộc trò chuyện là nó chấp nhận được cho một anh chàng nhìn chằm chằm vào bạn trống rỗng trong câu trả lời thực tế cho câu hỏi của bạn?

Cách thứ hai là sử dụng các hộp thoại phương thức, như hộp thoại jQuery, để yêu cầu thông tin này. Bạn sẽ nhận được toàn quyền điều khiển nó và ứng dụng sẽ không giống như nó đã được thực hiện trong 1996.

+4

trả lời đầu tiên của bạn là vô ích. Có nhiều lý do khiến chuỗi rỗng có thể là phản hồi hợp lệ.Thứ hai của bạn không phải là hữu ích khủng khiếp, hoặc, tôi không phải là về để khai thác thông qua nguồn của JQuery cố gắng để tìm hiểu những gì nó có thể được làm cho một "hộp thoại phương thức". – Anomie

+0

Lý thuyết khá đơn giản, bạn đặt "div" lớn bao gồm toàn bộ khung nhìn sau đó hiển thị hộp thoại của bạn trên đó. Khi đóng hộp thoại, bạn xóa 'div' mà bạn đã tạo trước đó. Tất cả được gói gọn trong một cuộc gọi đơn giản '.dialog ('show')'! – Blindy

+1

Nhưng bạn không thể sử dụng kiểu hộp thoại đó như 'var retval = dialog ('show')'. Bạn sẽ phải thiết lập gọi lại cho hộp thoại giả của bạn để được gọi khi người dùng nhấp vào "Ok" hoặc "Hủy" và ngắt chức năng nhắc của bạn thành từng phần cho "trước" và "sau" hiển thị hộp thoại trong khi duy trì trạng thái giữa cả hai. Khi tôi muốn điều đó, tôi đã làm được rồi. Nhưng đôi khi một dấu nhắc đơn giản() là tất cả những gì cần thiết để yêu cầu người dùng cung cấp thông tin cần thiết. – Anomie

3
var res = prompt('hello?', '') 
if (res === null || res === '' && isSafari && confirm('was that cancel?')) 
    cancel 
+1

Tôi hy vọng bạn có ý nghĩa này như một rant. – pimvdb

+0

+1, chỉ vì tôi đã làm điều tương tự như một biện pháp dừng chân khi lần đầu tiên tôi gặp phải lỗi này. – Anomie

3

Tôi đánh giá cao Thủ trưởng lên-tôi đã không nhận thấy hành vi đó, nhưng bây giờ tôi thấy rằng bạn đang chính xác. Safari 5 hoạt động bình thường, 5.1 trả về một chuỗi trống cho một trong hai nút bấm, nếu có một chuỗi rỗng trong trường nhắc.

Đề xuất duy nhất của tôi là đặt ký tự khoảng trắng vào trường để bắt đầu. Chỉ nút 'OK' sẽ trả lại khoảng trống, hủy sẽ trả về giá trị rỗng hoặc chuỗi rỗng.

var p=prompt('what dya say?',' '); 
if(!p)// cancel was *probably* clicked 
else if(p===' ')//ok was clicked with no input 
else// there is user input 

Người dùng thể bắt đầu nhập một cái gì đó, hãy xóa nó, và sau đó nhấn 'ok' thay vì hủy bỏ, nhưng mà loại từng trường hợp cũng được một hủy.

0

Tôi tryed và điều này làm việc cho tôi

var location=""; 
    var p=prompt("type your location",location); 

if(p!==null) { location = p; alert("ok do query"); }