¿Cómo mostrar un cuadro de diálogo de confirmación al hacer clic en un enlace <a>?

269

Quiero que este enlace tenga un diálogo de JavaScript que pregunte al usuario " ¿Estás seguro? S / N ".

<a href="delete.php?id=22">Link</a>

Si el usuario hace clic en "Sí", el enlace debe cargarse, si "No" no pasará nada.

Sé cómo hacerlo en formularios, usando onclickejecutar una función que devuelve trueo false. Pero, ¿cómo hago esto con un <a>enlace?

Christoffer
fuente
Cómo podemos lograr esto angularjs1.x
Bhaskara Arani

Respuestas:

597

Controlador de eventos en línea

De la manera más simple, puede usar la confirm()función en un onclickcontrolador en línea .

<a href="delete.php?id=22" onclick="return confirm('Are you sure?')">Link</a>

Manejo avanzado de eventos

Pero normalmente le gustaría separar su HTML y Javascript , por lo que le sugiero que no use controladores de eventos en línea, sino que coloque una clase en su enlace y agregue un detector de eventos.

<a href="delete.php?id=22" class="confirmation">Link</a>
...
<script type="text/javascript">
    var elems = document.getElementsByClassName('confirmation');
    var confirmIt = function (e) {
        if (!confirm('Are you sure?')) e.preventDefault();
    };
    for (var i = 0, l = elems.length; i < l; i++) {
        elems[i].addEventListener('click', confirmIt, false);
    }
</script>

Este ejemplo sólo funcionará en los navegadores modernos (por IEs de edad avanzada se puede utilizar attachEvent(), returnValuey proporcionar una implementación para getElementsByClassName()o utilizar una biblioteca como jQuery que le ayudará con problemas de cross-browser). Puede leer más sobre este método avanzado de manejo de eventos en MDN .

jQuery

Me gustaría estar lejos de ser considerado un fanático de jQuery, pero la manipulación del DOM y el manejo de eventos son dos áreas donde ayuda más con las diferencias del navegador. Solo por diversión, así es como se vería con jQuery :

<a href="delete.php?id=22" class="confirmation">Link</a>
...
<!-- Include jQuery - see http://jquery.com -->
<script type="text/javascript">
    $('.confirmation').on('click', function () {
        return confirm('Are you sure?');
    });
</script>
kapa
fuente
¿Fue realmente así de fácil! ¿Estoy avergonzado o qué? Supuse que solo funcionaba en formularios. ¿Funciona el diálogo de confirmación para cada elemento en el que se puede hacer clic?
Christoffer
1
@Tophe El diálogo de confirmación en sí no tiene nada que ver con elementos específicos.
kapa
1
Para algo tan simple como esto, ¿es realmente necesario separar el HTML y JavaScript? ¿Qué problemas preveería si dejara una función tan simple y corta en línea?
Ciaran Gallagher
55
@CiaranG Siempre comienza así :), luego agrega esto y aquello, etc. Si logra abrazar la separación de preocupaciones, se sentirá más limpio si se deshace de la mayoría de estos controladores en línea. Simplemente no tienen nada que hacer en tu HTML. Al menos en mi opinión, y al menos en la mayoría de los casos. Siempre hay circunstancias especiales: la pereza no debería ser una de ellas.
kapa
@Ulysnep De acuerdo con su sugerencia de edición, hubo un error al omitir el punto y coma después confirm(…)en el controlador en línea. No pude reproducir eso.
user4642212
15

Sugeriría evitar JavaScript en línea:

var aElems = document.getElementsByTagName('a');

for (var i = 0, len = aElems.length; i < len; i++) {
    aElems[i].onclick = function() {
        var check = confirm("Are you sure you want to leave?");
        if (check == true) {
            return true;
        }
        else {
            return false;
        }
    };
}​

Demostración de JS Fiddle .

Lo anterior actualizado para reducir el espacio, aunque manteniendo la claridad / función:

var aElems = document.getElementsByTagName('a');

for (var i = 0, len = aElems.length; i < len; i++) {
    aElems[i].onclick = function() {
        return confirm("Are you sure you want to leave?");
    };
}

Demostración de JS Fiddle .

Una actualización algo tardía, para usar addEventListener()(como se sugiere, por bažmegakapa , en los comentarios a continuación):

function reallySure (event) {
    var message = 'Are you sure about that?';
    action = confirm(message) ? true : event.preventDefault();
}
var aElems = document.getElementsByTagName('a');

for (var i = 0, len = aElems.length; i < len; i++) {
    aElems[i].addEventListener('click', reallySure);
}

Demostración de JS Fiddle .

Lo anterior vincula una función al evento de cada enlace individual; lo cual es potencialmente un desperdicio, cuando podría vincular el manejo de eventos (mediante delegación) a un elemento ancestro, como el siguiente:

function reallySure (event) {
    var message = 'Are you sure about that?';
    action = confirm(message) ? true : event.preventDefault();
}

function actionToFunction (event) {
    switch (event.target.tagName.toLowerCase()) {
        case 'a' :
            reallySure(event);
            break;
        default:
            break;
    }
}

document.body.addEventListener('click', actionToFunction);

Demostración de JS Fiddle .

Debido a que el manejo de eventos está asociado al bodyelemento, que normalmente contiene una gran cantidad de otros elementos en los que se puede hacer clic, he usado una función provisional ( actionToFunction) para determinar qué hacer con ese clic. Si el elemento cliqueado es un enlace y, por lo tanto, tiene un tagNamede a, el manejo de clics se pasa a la reallySure()función.

Referencias

David dice reinstalar a Mónica
fuente
Gracias. La breve solución de confirmación en línea funcionó. ¿Por qué sugiere evitar el código en línea? Por lo general, me mantengo alejado de CSS en línea por razones obvias, pero ¿cuáles son las razones en fragmentos cortos de JavaScript?
Christoffer
Por exactamente la misma razón por la que no se recomienda CSS en línea, es más difícil de mantener, y conduce a HTML más desordenado y requiere una cantidad excesiva de trabajo para actualizar si los requisitos cambian.
David dice que reinstale a Mónica
Estoy de acuerdo con el punto de no usar controladores en línea. Pero si de todos modos adjuntamos nuestros controladores en el script, se debe usar el modelo avanzado ( addEventListener). +1 sin embargo.
kapa
@ bažmegakapa: Yo ... tiendo a estar de acuerdo; pero debo confesar que aún no me he sentido cómodo con el addEventListener()modelo.
David dice que reinstale a Mónica
Se puede reemplazar if(check == true)con if(check).
Anónimo
14
<a href="delete.php?id=22" onclick = "if (! confirm('Continue?')) { return false; }">Confirm OK, then goto URL (uses onclick())</a>
descifrador
fuente
5

También puedes probar esto:

<a href="" onclick="if (confirm('Delete selected item?')){return true;}else{event.stopPropagation(); event.preventDefault();};" title="Link Title">
    Link Text
</a>
Wolfack
fuente
La respuesta dada por @kapa es muy fácil y menos complicada
dipenparmar12
1

jAplus

Puedes hacerlo sin escribir código JavaScript

<head>
   <script src="/path/to/jquery.js" type="text/javascript" charset="utf-8"></script>
   <script src="/path/to/jquery.Aplus.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
...
   <a href="delete.php?id=22" class="confirm" title="Are you sure?">Link</a>
...
</body>

Página de demostración

erik
fuente
11
Gracias por compartir, pero, por supuesto, está utilizando Javascript, está agregando una biblioteca completa para manejar algo muy simple. ¿Vale la pena? No conozco esa biblioteca, leeré sobre ella, si la usa también para otros fines, tal vez valga la pena la carga adicional ...
Marcos Buarque
1
¿Dos bibliotecas para esta cosa simple?
maracuja-juice
0

Este método es ligeramente diferente de cualquiera de las respuestas anteriores si adjunta su controlador de eventos usando addEventListener (o attachEvent).

function myClickHandler(evt) {
  var allowLink = confirm('Continue with link?');
  if (!allowLink) {
    evt.returnValue = false; //for older Internet Explorer
    if (evt.preventDefault) {
      evt.preventDefault();
    }
    return false;
  }
}

Puede adjuntar este controlador con:

document.getElementById('mylinkid').addEventListener('click', myClickHandler, false);

O para versiones anteriores de Internet Explorer:

document.getElementById('mylinkid').attachEvent('onclick', myClickHandler);
Chad Killingsworth
fuente
Si te preocupan los viejos IE, no lo olvides window.event.
kapa
0

Solo por diversión, voy a usar un solo evento en todo el documento en lugar de agregar un evento a todas las etiquetas de anclaje:

document.body.onclick = function( e ) {
    // Cross-browser handling
    var evt = e || window.event,
        target = evt.target || evt.srcElement;

    // If the element clicked is an anchor
    if ( target.nodeName === 'A' ) {

        // Add the confirm box
        return confirm( 'Are you sure?' );
    }
};

Este método sería más eficiente si tuviera muchas etiquetas de anclaje. Por supuesto, se vuelve aún más eficiente cuando agrega este evento al contenedor que tiene todas las etiquetas de anclaje.

Florian Margaine
fuente
0

La mayoría de los navegadores no muestran el mensaje personalizado pasado confirm().

Con este método, puede mostrar una ventana emergente con un mensaje personalizado si su usuario cambió el valor de cualquier <input>campo.

Puede aplicar esto solo a algunos enlaces , o incluso a otros elementos HTML en su página. Simplemente agregue una clase personalizada a todos los enlaces que necesitan confirmación y aplique el siguiente código:

$(document).ready(function() {
  let unsaved = false;
  // detect changes in all input fields and set the 'unsaved' flag
  $(":input").change(() => unsaved = true);
  // trigger popup on click
  $('.dangerous-link').click(function() {
    if (unsaved && !window.confirm("Are you sure you want to nuke the world?")) {
      return; // user didn't confirm
    }
    // either there are no unsaved changes or the user confirmed
    window.location.href = $(this).data('destination');
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<input type="text" placeholder="Nuclear code here" />
<a data-destination="https://en.wikipedia.org/wiki/Boom" class="dangerous-link">
    Launch nuke!
</a>

Intente cambiar el valor de entrada en el ejemplo para obtener una vista previa de cómo funciona.

Salvioner
fuente
-2

USO DE PHP, HTML Y JAVASCRIPT para solicitar

Solo si alguien busca usar php, html y javascript en un solo archivo, la respuesta a continuación está funcionando para mí ... adjunto con el ícono de arranque "basura" para el enlace.

<a class="btn btn-danger" href="<?php echo "delete.php?&var=$var"; ?>" onclick="return confirm('Are you sure want to delete this?');"><span class="glyphicon glyphicon-trash"></span></a>

la razón por la que usé el código php en el medio es porque no puedo usarlo desde el principio ...

el siguiente código no funciona para mí: -

echo "<a class='btn btn-danger' href='delete.php?&var=$var' onclick='return confirm('Are you sure want to delete this?');'><span class='glyphicon glyphicon-trash'></span></a>";

y lo modifiqué como en el primer código, luego ejecuto exactamente lo que necesito. Espero que pueda ayudar a alguien que no conozca mi caso.

Shah Abd Hafiz
fuente