2011-09-08 17 views
15

En la mayoría de los navegadores (incluidas versiones anteriores de Safari), la función Javascript prompt devuelve null cuando el usuario hace clic en "Cancelar" y la cadena vacía si el usuario hace clic en "Aceptar" sin nada en el cuadro de texto. Pero en Safari 5.1, devuelve la cadena vacía para ambos casos.Safari 5.1 prompt() función y cancelar

Utilicé la función "informar un error" de Safari para informarlo a Apple, pero quién sabe cuándo podrían incluso reconocerlo y mucho menos arreglarlo. ¿Alguien tiene una solución alternativa?

Respuesta

2

He logrado encontrar una solución real, ya que Safari agregó soporte para showModalDialog() en 5.1. Muy conveniente, eso.

En primer lugar, crear un archivo con este contenido:

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

Entonces, para las versiones rotos de Safari (no parece haber ninguna manera de presentar detectar esto sin aparecer una pronta y preguntar al usuario para golpear "Cancelar", por lo que es probable que tenga que hacer una verificación User-Agent), ejecute el siguiente Javascript para reemplazar 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; 
})(); 

Por supuesto, cambiar la ruta /js/safari-5.1-bugfix.html a la ruta correcta a la creada por encima de la Archivo HTML en tu servidor Desafortunadamente, no podemos usar un data: URI ya que Safari aparentemente tiene otro error donde pierde window.dialogArguments e ignora window.returnValue para diálogos con data: URI.

Puede usar prompt() como lo haría normalmente.

+0

¡Agradable, gracias! – Bibou

-1

Seguro, dos de hecho.

Primero, obvio, rediseñe su sistema para que una cadena vacía no sea una respuesta válida. Piénselo, cuando en una conversación es aceptable que un hombre lo mire sin comprender en respuesta a su pregunta.

El segundo es usar cuadros de diálogo modales, como jQuery, para solicitar esta información. Usted obtendrá el control del mismo y la aplicación no se verá como se hizo en 1996.

+4

Su primera respuesta es inútil. Hay muchas razones por las que una cadena vacía podría ser una respuesta válida.Su segundo tampoco es muy útil, no voy a buscar en la fuente de JQuery tratando de averiguar qué podría estar haciendo para un "diálogo modal". – Anomie

+0

La teoría es bastante simple, pones un "div" "grande" que cubre toda la ventana gráfica y luego muestra tu diálogo sobre él. Al cerrar el cuadro de diálogo, elimina el 'div 'que creó anteriormente. ¡Todo está encapsulado en una simple llamada '.dialog ('show')'! – Blindy

+1

Pero no puede usar ese estilo de diálogo como 'var retval = dialog ('show')'. Debería configurar las devoluciones de llamada para su pseudo-diálogo cuando el usuario haga clic en "Aceptar" o "Cancelar" y dividir su función de aviso en partes para "antes" y "después" de la pantalla del diálogo mientras mantiene el estado entre los dos. Cuando quiero ese tipo de cosas, ya lo hago. Pero a veces un simple 'prompt()' es todo lo que se necesita para pedirle al usuario la información necesaria. – Anomie

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

Espero que te refieras a esto como una diatriba. – pimvdb

+0

+1, solo porque hice lo mismo que una medida provisional cuando encontré el error por primera vez. – Anomie

3

aprecio las cabezas UP que no había notado el comportamiento, pero ahora veo que son correcto. Safari 5 se comporta normalmente, 5.1 devuelve una cadena vacía para cualquier clic de botón, si hay una cadena vacía en el campo de solicitud.

Mi única sugerencia es poner un carácter de espacio en el campo para comenzar. Solo el botón "Aceptar" devolverá el espacio, cancelar devolverá nulo o la cadena vacía.

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 

El usuario podría comienzan a entrar en algo, borrarlo, y después haga clic en 'Aceptar' en lugar de cancelar, pero ese tipo de caso puede también ser una cancelar.

0

He probado y esto funcionó para mí

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

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