javascript - disabled - Cómo deshabilitar enlaces HTML
title css (12)
Tengo un botón de enlace dentro de un <td>
que tengo que deshabilitar. Esto funciona en IE pero no funciona en Firefox y Chrome. Estructura es - Enlace dentro de un <td>
. No puedo agregar ningún contenedor en <td>
(como div / span)
Probé todo lo siguiente pero no funcionó en Firefox (usando 1.4.2 js):
$(td).children().each(function () {
$(this).attr(''disabled'', ''disabled'');
});
$(td).children().attr(''disabled'', ''disabled'');
$(td).children().attr(''disabled'', true);
$(td).children().attr(''disabled'', ''true'');
Nota: no puedo anular el registro de la función de clic para la etiqueta de anclaje ya que se registra dinámicamente. Y TENGO QUE MOSTRAR EL ENLACE EN MODO DISCAPACITADO.
Bootstrap 4.1 proporciona una clase llamada disabled
y aria-disabled="true"
atributo aria-disabled="true"
.
ejemplo"
<a href="#"
class="btn btn-primary btn-lg disabled"
tabindex="-1"
role="button" aria-disabled="true"
>
Primary link
</a>
Entonces, si quieres hacerlo de forma dinámica, y you don''t want to care if it is button or ancor
que en el script JS, necesitas algo así.
let $btn=$(''.myClass'');
$btn.attr(''disabled'', true);
if ($btn[0].tagName == ''A''){
$btn.off();
$btn.addClass(''disabled'');
$btn.attr(''aria-disabled'', true);
}
Pero ten cuidado
La solución solo funciona en enlaces con clases btn btn-link
.
A veces, bootstrap recomienda usar la clase de card-link
, en este caso la solución no funcionará .
Consiguió la corrección en css.
td.disabledAnchor a{
pointer-events: none !important;
cursor: default;
color:Gray;
}
Sobre css, cuando se aplica a la etiqueta de anclaje, se deshabilitará el evento de clic.
Para más detalles consulte este enlace
Creo que muchos de estos están sobre pensando. Agrega una clase de lo que quieras, como disabled_link
.
Luego haga que el css tenga .disabled_link { display: none }
Boom ahora el usuario no puede ver el enlace, por lo que no tendrá que preocuparse por hacer clic en él. Si hacen algo para satisfacer el enlace haciendo clic, simplemente elimine la clase con jQuery:
$("a.disabled_link").removeClass("super_disabled")
. ¡Boom hecho!
Gracias a todos los que publicaron soluciones (especialmente @AdrianoRepetti), combiné varios enfoques para proporcionar algunas funcionalidades más avanzadas y disabled
(y funciona en varios navegadores). El código está abajo (tanto ES2015 como coffeescript basado en su preferencia).
Esto proporciona múltiples niveles de defensa para que los Anclajes marcados como deshabilitados realmente se comporten como tales. Usando este enfoque, obtienes un ancla que no puedes:
- hacer clic
- pestaña y pulsa retorno
- tabularlo moverá el foco al siguiente elemento enfocable
- es consciente si el ancla se habilita posteriormente
Cómo
Incluye este css, ya que es la primera línea de defensa. Esto supone que el selector que utiliza está
a.disabled
a.disabled { pointer-events: none; cursor: default; }
A continuación, cree una instancia de esta clase en listo (con selector opcional):
new AnchorDisabler()
Clase ES2015
npm install -S key.js
import {Key, Keycodes} from ''key.js''
export default class AnchorDisabler {
constructor (config = { selector: ''a.disabled'' }) {
this.config = config
$(this.config.selector)
.click((ev) => this.onClick(ev))
.keyup((ev) => this.onKeyup(ev))
.focus((ev) => this.onFocus(ev))
}
isStillDisabled (ev) {
// since disabled can be a class or an attribute, and it can be dynamically removed, always recheck on a watched event
let target = $(ev.target)
if (target.hasClass(''disabled'') || target.prop(''disabled'') == ''disabled'') {
return true
}
else {
return false
}
}
onFocus (ev) {
// if an attempt is made to focus on a disabled element, just move it along to the next focusable one.
if (!this.isStillDisabled(ev)) {
return
}
let focusables = $('':focusable'')
if (!focusables) {
return
}
let current = focusables.index(ev.target)
let next = null
if (focusables.eq(current + 1).length) {
next = focusables.eq(current + 1)
} else {
next = focusables.eq(0)
}
if (next) {
next.focus()
}
}
onClick (ev) {
// disabled could be dynamically removed
if (!this.isStillDisabled(ev)) {
return
}
ev.preventDefault()
return false
}
onKeyup (ev) {
// We are only interested in disabling Enter so get out fast
if (Key.isNot(ev, Keycodes.ENTER)) {
return
}
// disabled could be dynamically removed
if (!this.isStillDisabled(ev)) {
return
}
ev.preventDefault()
return false
}
}
Clase coffescript
class AnchorDisabler
constructor: (selector = ''a.disabled'') ->
$(selector).click(@onClick).keyup(@onKeyup).focus(@onFocus)
isStillDisabled: (ev) =>
### since disabled can be a class or an attribute, and it can be dynamically removed, always recheck on a watched event ###
target = $(ev.target)
return true if target.hasClass(''disabled'')
return true if target.attr(''disabled'') is ''disabled''
return false
onFocus: (ev) =>
### if an attempt is made to focus on a disabled element, just move it along to the next focusable one. ###
return unless @isStillDisabled(ev)
focusables = $('':focusable'')
return unless focusables
current = focusables.index(ev.target)
next = (if focusables.eq(current + 1).length then focusables.eq(current + 1) else focusables.eq(0))
next.focus() if next
onClick: (ev) =>
# disabled could be dynamically removed
return unless @isStillDisabled(ev)
ev.preventDefault()
return false
onKeyup: (ev) =>
# 13 is the js key code for Enter, we are only interested in disabling that so get out fast
code = ev.keyCode or ev.which
return unless code is 13
# disabled could be dynamically removed
return unless @isStillDisabled(ev)
ev.preventDefault()
return false
Hay otra forma posible, y la que más me gusta. Básicamente es la misma forma en que lightbox desactiva una página completa, colocando un div y jugando con el índice z. Aquí hay fragmentos relevantes de un proyecto mío. Esto funciona en todos los navegadores !!!!!
Javascript (jQuery):
var windowResizer = function(){
var offset = $(''#back'').offset();
var buttontop = offset.top;
var buttonleft = offset.left;
$(''#backdisabler'').css({''top'':buttontop,''left'':buttonleft,''visibility'':''visible''});
offset = $(''#next'').offset();
buttontop = offset.top;
buttonleft = offset.left;
$(''#nextdisabler'').css({''top'':buttontop,''left'':buttonleft,''visibility'':''visible''});
}
$(document).ready(function() {
$(window).resize(function() {
setTimeout(function() {
windowResizer();
}, 5); //when the maximize/restore buttons are pressed, we have to wait or it will fire to fast
});
});
y en html
<a href="" id="back" style="float: left"><img src="images/icons/back.png" style="height: 50px; width: 50px" /></a>
<a href="" id="next" style="float: right"><img src="images/icons/next.png" style="height: 50px; width: 50px" /></a>
<img id="backdisabler" src="images/icons/disabled.png" style="visibility: hidden; position: absolute; padding: 5px; height: 62px; width: 62px; z-index: 9000"/>
<img id="nextdisabler" src="images/icons/disabled.png" style="visibility: hidden; position: absolute; padding: 5px; height: 62px; width: 62px; z-index: 9000"/>
Así que el redimensionador encuentra las ubicaciones del ancla (las imágenes son solo flechas) y coloca al deshabilitador en la parte superior. La imagen del deshabilitador es un cuadrado gris translúcido (cambie el ancho / alto de los deshabilitadores en el html para que coincida con su enlace) para mostrar que está deshabilitado. El flotante permite que la página cambie de tamaño dinámicamente, y los desactivadores seguirán su ejemplo en windowResizer (). Puedes encontrar imágenes adecuadas a través de google. He colocado el css relevante en línea para la simplicidad.
luego basado en alguna condición,
$(''#backdisabler'').css({''visibility'':''hidden''});
$(''#nextdisabler'').css({''visibility'':''visible''});
No puedes deshabilitar un enlace (de una manera portátil). Puede utilizar una de estas técnicas (cada una con sus propios beneficios y desventajas).
Forma CSS
Esta debería ser la forma correcta (pero ver más adelante) para hacerlo cuando la mayoría de los navegadores lo admitirán:
a.disabled {
pointer-events: none;
}
Es lo que, por ejemplo, Bootstrap 3.x hace. Actualmente (2016) está bien soportado solo por Chrome, FireFox y Opera (19+). Internet Explorer comenzó a admitir esto desde la versión 11, pero no para enlaces, sin embargo, está disponible en un elemento externo como:
span.disable-links {
pointer-events: none;
}
Con:
<span class="disable-links"><a href="#">...</a></span>
Solución
Probablemente, necesitamos definir una clase CSS para pointer-events: none
de pointer-events: none
pero ¿qué pasa si reutilizamos el atributo disabled
lugar de una clase CSS? Hablando estrictamente disabled
no es compatible con <a>
pero los navegadores no se quejarán de atributos desconocidos . El uso del atributo disabled
IE ignorará pointer-events
pero respetará el atributo disabled
específico de IE; otros navegadores compatibles con CSS ignorarán disabled
atributos disabled
desconocidos y respetarán los pointer-events
. Más fácil de escribir que de explicar:
a[disabled] {
pointer-events: none;
}
Otra opción para IE 11 es configurar la display
de los elementos de enlace para block
o en inline-block
:
<a style="pointer-events: none; display: inline-block;" href="#">...</a>
Tenga en cuenta que esta puede ser una solución portátil si necesita compatibilidad con IE (y puede cambiar su HTML) pero ...
Dicho todo esto, tenga en cuenta que pointer-events
puntero solo deshabilitan ... los eventos de puntero. Los enlaces seguirán siendo navegables a través del teclado, entonces también debe aplicar una de las otras técnicas que se describen aquí.
Atención
Junto con la técnica CSS descrita anteriormente, puede usar tabindex
de una manera no estándar para evitar que un elemento se enfoque:
<a href="#" disabled tabindex="-1">...</a>
Nunca verifiqué su compatibilidad con muchos navegadores, entonces es posible que desee probarlo usted mismo antes de usar esto. Tiene la ventaja de trabajar sin JavaScript. Desafortunadamente (pero obviamente) tabindex
no se puede cambiar desde CSS.
Interceptar clics
Use un href
para una función de JavaScript, verifique la condición (o el propio atributo deshabilitado) y no haga nada en el caso.
$("td > a").on("click", function(event){
if ($(this).is("[disabled]")) {
event.preventDefault();
}
});
Para deshabilitar enlaces haz esto:
$("td > a").attr("disabled", "disabled");
Para volver a habilitarlos:
$("td > a").removeAttr("disabled");
Si quiere en lugar de .is("[disabled]")
puede usar .attr("disabled") != undefined
Indefinido (jQuery 1.6+ siempre devolverá undefined
cuando el atributo no está establecido) pero is()
es mucho más claro (Gracias a Dave Stewart por este consejo). Tenga en cuenta que aquí estoy usando el atributo disabled
de una manera no estándar, si le importa esto, entonces reemplace el atributo con una clase y reemplace .is("[disabled]")
con .hasClass("disabled")
(agregando y eliminando con addClass()
y removeClass()
).
Zoltán Tamási señaló en un comentario que "en algunos casos el evento click ya está vinculado a alguna función" real "(por ejemplo, utilizando knockoutjs) En ese caso, el orden del controlador de eventos puede causar algunos problemas. Por lo tanto, implementé enlaces deshabilitados vinculando una devolución. controlador falso para los touchstart
de touchstart
, vinculación del touchstart
y keydown
mousedown
keydown
. Tiene algunos inconvenientes (evitará que se inicie el desplazamiento táctil en el enlace) ", pero el manejo de los eventos del teclado también tiene la ventaja de evitar la navegación con el teclado.
Tenga en cuenta que si href
no se borra, es posible que el usuario visite manualmente esa página.
Borrar el enlace
Borrar el atributo href
. Con este código no agrega un controlador de eventos, pero cambia el enlace en sí. Use este código para deshabilitar enlaces:
$("td > a").each(function() {
this.data("href", this.attr("href"))
.attr("href", "javascript:void(0)")
.attr("disabled", "disabled");
});
Y este para volver a habilitarlos:
$("td > a").each(function() {
this.attr("href", this.data("href")).removeAttr("disabled");
});
Personalmente no me gusta mucho esta solución (si no tiene que hacer más con los enlaces deshabilitados), pero puede ser más compatible debido a las diversas formas de seguir un enlace.
Fake click handler
Agregue / elimine una función onclick
donde return false
, no se seguirá el enlace. Para deshabilitar enlaces:
$("td > a").attr("disabled", "disabled").on("click", function() {
return false;
});
Para volver a habilitarlos:
$("td > a").removeAttr("disabled").off("click");
No creo que haya una razón para preferir esta solución en lugar de la primera.
Estilo
El estilo es aún más simple, sea cual sea la solución que esté utilizando para deshabilitar el enlace, agregamos un atributo disabled
para que pueda usar la siguiente regla CSS:
a[disabled] {
color: gray;
}
Si estás usando una clase en lugar de un atributo:
a.disabled {
color: gray;
}
Si está utilizando un marco de interfaz de usuario, puede ver que los enlaces deshabilitados no tienen el estilo correcto. Bootstrap 3.x, por ejemplo, maneja este escenario y el botón tiene el estilo correcto tanto con el atributo disabled
como con la clase .disabled
. Si, en cambio, está borrando el enlace (o utilizando una de las otras técnicas de JavaScript), también debe manejar el estilo porque una <a>
sin href
todavía se pinta como habilitada.
Aplicaciones de Internet enriquecidas accesibles (ARIA)
No olvide incluir también un atributo aria-disabled="true"
junto con el atributo / clase disabled
.
Para desactivar el enlace para acceder a otra página en el dispositivo táctil.
if (control == false)
document.getElementById(''id_link'').setAttribute(''href'', '''');
else
document.getElementById(''id_link'').setAttribute(''href'', ''page/link.html'');
end if;
Prueba el elemento:
$(td).find(''a'').attr(''disabled'', ''disabled'');
Deshabilitar un enlace funciona para mí en Chrome: http://jsfiddle.net/KeesCBakker/LGYpz/ .
Firefox no parece jugar bien. Este ejemplo funciona:
<a id="a1" href="http://www.google.com">Google 1</a>
<a id="a2" href="http://www.google.com">Google 2</a>
$(''#a1'').attr(''disabled'', ''disabled'');
$(document).on(''click'', ''a'', function(e) {
if ($(this).attr(''disabled'') == ''disabled'') {
e.preventDefault();
}
});
Nota: se agregó una declaración ''en vivo'' para futuros enlaces deshabilitados / habilitados.
Nota2: se cambió ''live'' en ''on''.
Puede usar esto para deshabilitar el hipervínculo de asp.net o los botones de enlace en html.
$("td > a").attr("disabled", "disabled").on("click", function() {
return false;
});
Terminé con la solución a continuación, que puede funcionar con un atributo, <a href="..." disabled="disabled">
, o una clase <a href="..." class="disabled">
:
Estilos CSS:
a[disabled=disabled], a.disabled {
color: gray;
cursor: default;
}
a[disabled=disabled]:hover, a.disabled:hover {
text-decoration: none;
}
Javascript (en jQuery listo):
$("a[disabled], a.disabled").on("click", function(e){
var $this = $(this);
if ($this.is("[disabled=disabled]") || $this.hasClass("disabled"))
e.preventDefault();
})
Yo haria algo como
$(''td'').find(''a'').each(function(){
$(this).addClass(''disabled-link'');
});
$(''.disabled-link'').on(''click'', false);
Algo como esto debería funcionar. Agrega una clase para los enlaces que desea desactivar y luego devuelve falso cuando alguien hace clic en ellos. Para habilitarlos solo quita la clase.
no puede deshabilitar un enlace, si desea que el evento de clic no se dispare, simplemente Remove
la action
de ese enlace.
$(td).find(''a'').attr(''href'', '''');
Para más información: - Elementos que pueden ser desactivados.