javascript - boton - Activar un evento de clic en un elemento interno
onclick php (14)
Una fila en una tabla donde cada primera celda contiene un enlace debe hacerse clic y abrir una url.
<table>
<tr>
<td><a class="fancybox" href="detail.aspx?CID=67525">LT5C260A436C41</a></td>
<td>more data</td>
</tr>
<tr>
<td><a class="fancybox" href="detail.aspx?CID=17522">LA5C260D436C41</a></td>
<td>more data</td>
</tr>
...
</table>
La fila completa debe ser pulsable en lugar de solo la parte superior del enlace para abrir la página de detalles en un fancybox , es decir, en la propia página.
Así que intenté hacer algo como esto:
$("table tr").bind(''click'',function(e) {
e.stopPropagation();
$(this).find("a").trigger(''click'');
});
Pero parece que el evento está burbujeando recursivamente dando como resultado un:
Intervalo no detectado: se ha excedido el tamaño máximo de pila de llamadas
¿Cómo puedo activar el clic en la fila completa en lugar de solo el enlace de una manera adecuada evitando el flujo de apilamiento?
ACTUALIZACIÓN: Realmente aprecio las respuestas a continuación, pero mi pregunta es acerca de desencadenar el evento, NO de ejecutar el comportamiento dentro de ese evento. Las soluciones podrían ser agradables, pero no en este caso.
¿Ha intentado detener la propagación inmediata al hacer clic en el enlace? De esta manera debería detener la recursión
$(''a'').click(function(e){
e.stopImmediatePropagation();
alert(''hi'');
});
violín aquí: http://jsfiddle.net/3VMGn/2/
Creo que .click()
o .trigger("click")
solo .trigger("click")
los controladores de eventos para onclick
.
Vea una muestra aquí http://jsfiddle.net/sethi/bEDPp/4/ . Al hacer clic manualmente en el enlace se muestran 2 alertas mientras se dispara el evento a través de jQuery muestra solo 1 alerta.
También puede consultar este enlace: reiniciar un evento de clic en un enlace con jQuery
Solución
Si solo buscas abrir un fancybox prueba esto:
$("table tr").bind(''click'',function(e) {
var elem = $(e.target);
if(elem.is(''a'')){
return;
}
e.stopImmediatePropagation();
var parent= elem.is(''tr'') ? elem:elem.parents("tr").eq(0);
parent.find("a").trigger(''click.fb'');
});
donde click.fb
es el evento que fancybox se enlaza con el elemento delimitador.
Creo que tengo lo que estás buscando. Lo que debe hacer es llamar a click()
en la etiqueta de anclaje en el controlador, y asegurarse de ignorar los eventos del propio ancla. Además, WebKit no admite click()
, por lo que debe implementarlo usted mismo.
Observe en el violín a continuación que sigue correctamente el objetivo del enlace, es decir, abre una nueva ventana o se carga en la misma ventana. http://jsfiddle.net/mendesjuan/5pv5A/3/
// Some browsers (WebKit) don''t support the click method on links
if (!HTMLAnchorElement.prototype.click) {
HTMLAnchorElement.prototype.click = function() {
var target = this.getAttribute(''target'');
var href = this.getAttribute(''href'');
if (!target) {
window.location = href;
} else {
window.open(href, target);
}
}
}
$("table tr").bind(''click'',function(e) {
// This prevents the
if (e.target.tagName == ''A'') {
return;
}
// This triggers the default behavior of the anchor
// unlike calling jQuery trigger(''click'')
$(this).find("a").get(0).click();
});
Esto funcionó bien:
$("table tr").click(function(e) {
var $link = $(this).find("a");
if (e.target === $link[0]) return false;
$link.trigger(''click'');
return false;
});
EDITAR:
¿Por qué la mayoría de las soluciones no funcionan ? Fallan, porque cuando se hace clic en el enlace, se ejecuta el controlador inmediato adjunto. El evento luego burbujea para ver si un controlador se adjuntó a una celda de tabla, fila, etc.
Cuando sugiere que se active un clic, se produce la recursión: se hizo clic en el enlace → fancybox → bubbles → aha! fila de la tabla → activar el enlace, haga clic en el enlace → se hizo clic en el enlace ...
Cuando sugiera detener la propagación, tenga en cuenta que el evento deja de propagarse a los elementos principales, por lo que no se ejecutará un controlador de click
adjunto al body
.
Por qué funciona el código anterior : verificamos si el evento surgió de un enlace. Si es verdad, simplemente regresamos y detenemos la propagación.
Vea el fiddle actualizado: http://jsfiddle.net/F5aMb/28/
Mi caso de uso era activar un clic cuando se hacía clic en un elemento. La comprobación del tipo de elemento de destino resuelve el problema de la llamada recursiva.
$(''#table tbody td'').click(function(e){
if ($(e.target).is(''td'')) {
$(this).find(''input'').trigger(''click'');
}
});
Para compensar el burbujeo, debe detectar el objetivo del evento y no hacer clic en el enlace más de una vez. Además, la función de "activación" de jQuery no funcionará para enlaces simples, por lo que necesita una función de clic especializada.
Puede probarlo en: http://jsfiddle.net/F5aMb/27/
$("table tr").each(function(i, tr){
$(tr).bind(''click'',function(e) {
var target = $(e.target);
if( !target.is("a") ) {
clickLink($(this).find("a")[0]);
}
})
});
function clickLink(element) {
if (document.createEvent) {
// dispatch for firefox + others
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true ); // event type,bubbling,cancelable
return !element.dispatchEvent(evt);
} else {
//IE
element.click()
}
}
Para el divertido propósito de este ejercicio, aquí hay una solución js pura, es decir, sin usar jQ lib).
Disponible aquí para pruebas: http://jsfiddle.net/Sr5Vy/3/
<table>
<tr id="node_1">
<td><a class="fancybox" href="detail.aspx?CID=67525">LT5C260A436C41</a></td>
<td>more data</td>
</tr>
<tr id="node_2">
<td><a class="fancybox" href="detail.aspx?CID=17522">LA5C260D436C41</a></td>
<td>more data</td>
</tr>
</table>
function AddEvent(id, evt_type, ma_fonction, phase) {
var oElt = document.getElementById(id);
if( oElt.addEventListener ) {
oElt.addEventListener(evt_type, ma_fonction, phase);
} else if( oElt.attachEvent ) {
oElt.attachEvent(''on''+evt_type, ma_fonction);
}
// Debug
// alert(''a /''' + evt_type + ''/' event has been attached on '' + id );
return false;
}
function getElementsByRegExpOnId(search_reg, search_element, search_tagName) {
search_element = (search_element === undefined) ? document : search_element;
search_tagName= (search_tagName === undefined) ? ''*'' : search_tagName;
var id_return = new Array;
for(var i = 0, i_length = search_element.getElementsByTagName(search_tagName).length; i < i_length; i++) {
if (search_element.getElementsByTagName(search_tagName).item(i).id &&
search_element.getElementsByTagName(search_tagName).item(i).id.match(search_reg)) {
id_return.push(search_element.getElementsByTagName(search_tagName).item(i).id) ;
}
}
return id_return; // array
}
function FollowSpecialLinks(event) {
// Debug
// alert(''event was successfully attached'');
// Prevent propagation
event.preventDefault();
// Identify targetted node (eg one of the children of <tr>)
var targetted_elt = ShowEventSource(event);
//alert(''Event/'s target : '' + targetted_elt);
// Extract the targetted url
if (targetted_elt == "A") {
var current_link = GetEventSource(event).href;
} else {
var current_tr = GetEventSource(event).parentNode;
var child_links = current_tr.getElementsByTagName(''a'');
var current_link = child_links[0].href;
}
// Now open the link
if(current_link) {
// Debug
alert(''will now open href : '' + current_link);
window.location = current_link;
}
}
function GetEventSource(event) {
var e = event || window.event;
var myelt = e.target || e.srcElement;
return myelt;
}
function ShowEventSource(event) {
var elmt;
var event = event || window.event; // W3C ou MS
var la_cible = event.target || event.srcElement;
if (la_cible.nodeType == 3) // Vs bug Safari
elmt = la_cible.parentNode;
else
elmt = la_cible.tagName;
return elmt;
}
// Get all document <tr> id''s and attach the "click" events to them
my_rows = new Array();
my_rows = getElementsByRegExpOnId(/^node_.+/, document , ''tr'') ;
if (my_rows) {
for (i=0; i< my_rows.length; i++ ) {
var every_row = document.getElementById( my_rows[i] ) ;
AddEvent(every_row.id, ''click'', FollowSpecialLinks, false);
}
}
Pude hacerlo dando a cada enlace una ID única y luego utilizando jQuery para configurar el evento de clic de esa ID única para redirigir la ventana a la página correspondiente.
Aquí está mi ejemplo de trabajo: http://jsfiddle.net/MarkKramer/F5aMb/2/
Y aquí está el código:
$(''#link1'').click(function(){
// do whatever I want here, then redirect
window.location.href = "detail.aspx?CID=67525";
});
$(''#link2'').click(function(){
// do whatever I want here, then redirect
window.location.href = "detail.aspx?CID=17522";
});
$("table tr").click(function(e) {
e.stopImmediatePropagation();
$(this).find("a").trigger(''click'');
});
Puede ser que haya malinterpretado tu pregunta, pero esto no hace lo que necesitas:
$("table tr").click(function(e) {
e.stopImmediatePropagation();
if (! $(e.target).is(''a'')) {
$(this).find("a").trigger(''click'');
}
});
Puedes hacer lo que quieras con el siguiente código. Lo probé en ti jsfilddle parece funcionar.
$("table tr").click(function(e) {
// check if click event is on link or not.
// if it''s link, don''t stop further propagation
// so, link href will be followed.
if($(e.target).attr(''class'')==''fancybox''){
alert(''you clicked link, so what next ?.'');
// else if click is happened somewhere else than link,
// stop the propagation, so that it won''t go in recursion.
}else{
alert(''no link clicked, :( '');
alert(''now clicking link prgrammatically'');
$(this).find(''a'').click();
e.preventDefault();
}
});
Déjame saber, si quieres lograr algo más que esto.
Tratar
$(".fancybox").parent(''td'').parent(''tr'').bind(''click'',function(e) {
e.stopPropagation();
$(this).find("a").trigger(''click'');
});
tratar
$(''table tr'').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
Prueba esto:
$("table tr a").bind(''click'', function(e) {
e.preventDefault();
window.open($(this).attr(''href''));
return false;
});
$("table tr").bind(''click'', function(e) {
$(this).find("a").trigger(''click'');
});
Encontré lo que salió mal.
En tu código,
$("table tr").bind(''click'',function(e) {
e.stopPropagation();
$(this).find("a").trigger(''click'');//This line again triggers a click event binded on the tr ELEMENT which contains the ''a'' ELEMENT. So it goes into a infinite loop.
});
Actualizar:
$("table tr").bind(''click'', function(e) {
window.location.href = $(this).find("a.fancybox").attr(''href'');
});
$(this).find("a").trigger(''click'');
en realidad no está activando el comportamiento predeterminado de la etiqueta de anclaje. Solo intenta activar un evento de clic si un evento de clic ya está vinculado a ese elemento explícitamente.
$(''a.fancybox'').click(function(evt){evt.stopPropagation())});
$(''table tr:has[.fancybox]'').click(function(evt){
$(this).find(''.fancybox'').trigger(''click'')
})