Safari 5.1 prompt() function and cancel

2019-01-26 04:56发布

问题:

In most browsers (including older versions of Safari), the Javascript prompt function returns null when the user clicks "Cancel", and the empty string if the user clicks "Ok" with nothing in the text box. But in Safari 5.1, it returns the empty string for both cases.

I used Safari's "report a bug" feature to report it to Apple, but who knows when they might even acknowledge it much less fix it. Does anyone have a workaround?

回答1:

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


回答2:

I appreciate the heads up- I hadn't noticed the behavior, but now I see that you are correct. Safari 5 behaves normally, 5.1 returns an empty string for either button click, if there is an empty string in the prompt field.

My only suggestion is to put a space character in the field to start with. Only the 'OK' button will return the space, cancel will return null or the empty string.

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

The user could start to enter something, delete it, and then hit 'ok' instead of cancel, but that kind of case may as well be a cancel.



回答3:

I've managed to come up with a real workaround, since Safari added support for showModalDialog() in 5.1. Awfully convenient, that.

First, create a file with this content:

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

Then, for broken versions of Safari (there seems to be no way to feature-detect this without popping up a prompt and asking the user to hit "Cancel", so you'll probably have to do a User-Agent check), execute the following Javascript to replace 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;
})();

Of course, change the path /js/safari-5.1-bugfix.html to the correct path to the above-created HTML file on your server. Unfortunately, we cannot use a data: URI as Safari apparently has another bug where it loses window.dialogArguments and ignores window.returnValue for dialogs with data: URIs.

You can then use prompt() as you normally would.



回答4:

I tryed and this worked for me

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

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


回答5:

Sure, two in fact.

First the obvious one, redesign your system so an empty string is not a valid response. Think about it, when in a conversation is it acceptable for one guy to stare at you blankly in actual answer to your question?

The second one is to use modal dialogs, like jQuery ones, to ask for this information. You'll get complete control over it and the application won't look like it was made in 1996.