Запустить событие click на внутреннем элементе
Строка в таблице, в которой каждая первая ячейка содержит ссылку, должна быть нажата и открыть 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>
Полная строка должна быть интерактивной, а не только ссылкой вверх, чтобы открыть страницу сведений в fancybox, то есть на самой странице.
Итак, я попытался сделать что-то вроде этого:
$("table tr").bind('click',function(e) {
e.stopPropagation();
$(this).find("a").trigger('click');
});
Но кажется, что событие бурлирует рекурсивно, что приводит к:
Uncaught RangeError: Максимальный размер стека вызовов
Как я могу вызвать щелчок по полной строке, а не только по правильной ссылке, избегая стекирования?
ОБНОВЛЕНИЕ: Я очень ценю ответы ниже, но мой вопрос о запуске события, НЕ выполняющий поведение внутри этого события. Обходные пути могут быть приятными, но не в этом случае.
Ответы
Ответ 1
Это сработало хорошо:
$("table tr").click(function(e) {
var $link = $(this).find("a");
if (e.target === $link[0]) return false;
$link.trigger('click');
return false;
});
EDIT:
Почему большинство решений не работают - они терпят неудачу, потому что когда ссылка была нажата, запускается непосредственный обработчик. Событие затем пузырьки, чтобы увидеть, был ли обработчик прикреплен к ячейке таблицы, строке и т.д.
Когда вы предлагаете запускать клик, вы вызываете рекурсию: нажата ссылка → fancybox → bubbles → aha! строка таблицы → вызвать ссылку нажмите → ссылка была нажата...
Когда вы предлагаете прекратить распространение, обратите внимание, что событие перестает пузыриться на родительские элементы, поэтому обработчик click
, прикрепленный к body
, не будет выполнен.
Почему работает код выше - мы проверяем, произошло ли событие по ссылке. Если true, мы просто возвращаем и останавливаем распространение далее.
Смотрите обновленную скрипту: http://jsfiddle.net/F5aMb/28/
Ответ 2
попробуйте
$('table tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
Ответ 3
Попробуйте следующее:
$("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');
});
Я нашел, что пошло не так.
В вашем коде
$("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.
});
Обновление:
Это будет сделано.
$("table tr").bind('click', function(e) {
window.location.href = $(this).find("a.fancybox").attr('href');
});
$(this).find("a").trigger('click');
фактически не запускает значение по умолчанию поведение якорной метки. Он просто пытается вызвать событие click, если событие click уже привязан к этому элементу явно.
Ответ 4
Возможно, я неправильно понял ваш вопрос, но не делает этого, что вам нужно:
$("table tr").click(function(e) {
e.stopImmediatePropagation();
if (! $(e.target).is('a')) {
$(this).find("a").trigger('click');
}
});
Ответ 5
Для забавной цели этого упражнения, здесь есть чисто js-решение, т.е. без использования jQ lib).
Доступно здесь для тестирования: 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\ 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 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);
}
}
Ответ 6
Try
$(".fancybox").parent('td').parent('tr').bind('click',function(e) {
e.stopPropagation();
$(this).find("a").trigger('click');
});
Ответ 7
Вы пытались остановить немедленное распространение при нажатии ссылки? Таким образом, вы должны остановить рекурсию
$('a').click(function(e){
e.stopImmediatePropagation();
alert('hi');
});
скрипка здесь: http://jsfiddle.net/3VMGn/2/
Ответ 8
Чтобы компенсировать пузырьки, вам нужно определить цель события и не нажимать на ссылку более одного раза.
Кроме того, функция jQuery "trigger" не работает для простых ссылок, поэтому вам нужна специализированная функция щелчка.
вы можете попробовать: 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()
}
}
Ответ 9
Я смог сделать это, предоставив каждой ссылке уникальный идентификатор, а затем с помощью jQuery установить событие click этого уникального идентификатора для перенаправления окна на соответствующую страницу.
Вот мой рабочий пример: http://jsfiddle.net/MarkKramer/F5aMb/2/
И вот код:
$('#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');
});
Ответ 10
Вы можете делать то, что хотите, с помощью следующего кода. Я тестировал его на вас, кажется, работает jsfilddle.
$("table tr").click(function(e) {
// check if click event is on link or not.
// if it 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();
}
});
Сообщите мне, если вы хотите достичь чего-то другого.
Ответ 11
Я думаю, что .click()
или .trigger("click")
запускает только обработчики событий для onclick
.
См. образец здесь http://jsfiddle.net/sethi/bEDPp/4/
, При ручном нажатии на ссылку отображаются 2 предупреждения при запуске события через jQuery, отображается только 1 предупреждение.
Вы также можете обратиться к этой ссылке: повторно запустить событие click по ссылке с jQuery
Решение
Если вы просто хотите открыть fancybox, попробуйте следующее:
$("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');
});
где click.fb
- это событие, которое fancybox связывает с элементом привязки.
Ответ 12
$('a.fancybox').click(function(evt){evt.stopPropagation())});
$('table tr:has[.fancybox]').click(function(evt){
$(this).find('.fancybox').trigger('click')
})
Ответ 13
Думаю, у меня есть то, что ты ищешь. Что вам нужно сделать, так это вызвать click()
в теге привязки в обработчике и убедиться, что вы игнорируете события из самого якоря. Кроме того, WebKit не поддерживает click()
, поэтому вы должны реализовать его самостоятельно.
Обратите внимание на приведенную ниже скрипту, что она правильно следует за целью ссылки, то есть открывает новое окно или загружается в одно и то же окно. 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 stack overflow
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();
});
Ответ 14
Мой запрос был вызван щелчком мыши, когда был нажат элемент -element. Проверка типа целевого элемента решает проблему рекурсивного вызова.
$('#table tbody td').click(function(e){
if ($(e.target).is('td')) {
$(this).find('input').trigger('click');
}
});