Safari 5.1中的prompt()函数和cancel

16
在大多数浏览器中(包括旧版本的Safari),JavaScript的prompt函数在用户单击“取消”时会返回null,而如果用户在文本框中什么也不输入并单击“确定”,则返回空字符串。但是,在Safari 5.1中,对于这两种情况它都返回空字符串。
我使用Safari的“报告问题”功能将其报告给了苹果公司,但是谁知道他们什么时候会认可它,更不用说修复它了。有人有解决办法吗?

同样的错误在7.1版Safari和8.0版中出现。 w3school解释说这是由Safari支持的,哈哈哈,好笑... - bArraxas
5个回答

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

1
我希望你的意思是发泄一下情绪。 - pimvdb
+1,只是因为我在第一次遇到这个错误时也采取了同样的权宜之计。 - Anomie

3

谢谢提醒 - 我没有注意到这种行为,但是现在我看到你是正确的。Safari 5的表现正常,5.1版本会在提示字段中有空字符串时返回一个空字符串,如果点击按钮。

我唯一的建议是先在字段中放置一个空格字符。 只有“确定”按钮会返回空格,取消将返回null或空字符串。

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

用户可能开始输入一些内容,然后删除它,最后点击“确定”而不是“取消”,但这种情况实际上与取消没有什么区别。

2

我找到了一个真正的解决方法,因为 Safari 5.1 版本添加了对 showModalDialog() 的支持。非常方便。

首先,创建包含如下内容的文件:

<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>

然后,对于损坏的Safari版本(似乎没有方法可以检测到这一点而不弹出提示并要求用户点击“取消”,因此您可能需要进行用户代理检查),执行以下Javascript来替换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;
})();

当然,将路径/js/safari-5.1-bugfix.html更改为您服务器上创建的HTML文件的正确路径。不幸的是,我们无法使用data: URI,因为Safari显然有另一个错误,在处理具有data: URI的对话框时会丢失window.dialogArguments并忽略window.returnValue
然后,您可以像往常一样使用prompt()

0

我试过了,这个方法对我有效。

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

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

-1

当然,实际上有两种方法。

第一种是显而易见的,重新设计系统,使空字符串不再是有效的响应。想一想,在对话中一个人盯着你茫然无措地回答你的问题是可以接受的吗?

第二种方法是使用模态对话框,比如jQuery对话框,来询问这些信息。您将完全掌控它,并且应用程序看起来不像是在1996年制作的。


4
你的第一个回答没什么用。空字符串可能是有效响应的许多原因之一。你的第二个回答也不太有用,我不会去查找JQuery源代码以了解它对“模态对话框”的处理方式。 - Anomie
理论很简单,您可以放置一个“大”的div覆盖整个视口,然后在其上显示对话框。关闭对话框时,删除之前创建的div即可。但是,这一切都封装在一个简单的.dialog('show')调用中! - Blindy
1
但是你不能像 var retval = dialog('show') 那样使用对话框的风格。你需要为伪对话框设置回调函数,以便在用户单击“确定”或“取消”时调用它,并将提示函数分成“前”和“后”两部分,同时在两者之间保持状态。当我需要那种东西时,我已经做到了。但有时候一个简单的 prompt() 就足以询问用户所需的信息。 - Anomie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接