Сделать <a>внутри jQuery автозаполненным кликабельным
Мне удалось добавить ссылку справа от элементов автозаполнения jQuery, используя следующий код:
function onClientSelect(event, ui) {
// My handling code goes here
event.preventDefault();
}
$("#mypage input[name='client']").autocomplete({
minLength: 1,
appendTo: $(this).parent(),
source: '/filter_client/',
select: onClientSelect,
focus: function (event, ui) {
event.preventDefault();
},
}).data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "</a>")
.appendTo(ul);
};
Мой сервер возвращает метку элемента в этом формате:
<div class="ac-item-lb">My Item Label</div>
<a class="ac-item-a" href="/url_to_go_to/" target="_blank">View Detail</a>
Что я хочу сделать, так это открыть ссылку на новой вкладке, когда я нажимаю "Просмотр детали", которая нажимает любую другую область, выполняемую onClientSelect, как обычно. Однако в данный момент щелчок левой кнопкой мыши по ссылке также выполняется onClientSelect
. Единственный способ открыть ссылку - щелкнуть среднюю колесо или правую кнопку мыши и выбрать "открыть в новой вкладке".
Я попытался связать обработчик события клика по ссылке с event.stopImmediatePropagation(), но это, похоже, не работает. Кто-нибудь знает, как это исправить?
Ответы
Ответ 1
Один из способов сделать это - определить пользовательскую функцию select
и не использовать <a>
для ссылок
HTML:
<div class="ui-widget">
<label for="tags">Tags:</label>
<input id="tags">
</div>
JS:
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"];
$("#tags").autocomplete({
source: availableTags,
select: function (event, ui) {
var elem = $(event.originalEvent.toElement);
if (elem.hasClass('ac-item-a')) {
var url = elem.attr('data-url');
event.preventDefault();
window.open(url, '_blank ');
}
}
}).data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append('<a>' + item.label + '<span class="ac-item-a" data-url="http://www.nba.com"> View Details</span></a>')
.appendTo(ul);
};
JSFIDDLE.
Ответ 2
Задумывались ли вы о том, чтобы установить условное выражение в обработчике кликов не preventDefault
, когда это та ссылка? Если вы проверите, должен ли элемент работать нормально, вы можете return
раньше, чем preventDefault
, а затем ссылка должна работать как обычно.
Вот пример (JSBin):
function clickHandler(e) {
// If the target element has the class `test-clickable` then the
// function will return early, before `preventDefault`.
if (this.className.indexOf('test-clickable') !== -1) {
return;
}
alert('That link is not clickable because of `preventDefault`');
e.preventDefault();
}
$('a').click(clickHandler);
a {
display: block;
}
a:after {
content: ' [class=' attr(class)']';
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<a class='test-clickable' href='http://www.google.com' target='_blank'>Link</a>
<a class='test-not-clickable' href='http://www.google.com' target='_blank'>Link</a>
</body>
</html>
Ответ 3
Амир, в отношении вашего ответа, я думаю, что открытие окна внутри функции javascript из события select может быть заблокировано PopupBlocker
pinghsien422, ваша сторона сервера должна вернуть Json и не полный html, если вы должны вернуть полный html, внесите следующие изменения:
1.Удалить функцию clientSelect
В функции renderDatap > необходим тег 2.No 'a'
$("#mypage input[name='client']").autocomplete({
minLength: 1,
appendTo: $(this).parent(),
source: '/filter_client/',
focus: function (event, ui) {
event.preventDefault();
},
}).data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append( item.label )
.appendTo(ul);
};
Ответ 4
Хорошо, событие jquery имеет приоритет над выбранным событием - независимо от того, что вы делаете, вы ничего не можете остановить. Но вы можете проксировать событие menuselect, а затем решить, следует ли его вызывать (jsfiddle).
var ac = $("#mypage input[name='client']").autocomplete({
minLength: 1,
appendTo: document.body,
source: availableTags,
focus: function (event, ui) {
event.preventDefault();
},
}).data("ui-autocomplete");
ac._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<div>"+item.label+"<a class='link' href='http://test'>(http://test)</a></div>")
.appendTo(ul);
};
var ms = $._data(ac.menu.element.get(0), 'events').menuselect[0].handler;
ac.menu.element.off("menuselect");
ac.menu.element.on("menuselect", function (ev) {
if($(ev.originalEvent.target).hasClass("link"))
return;
ms.apply(this,arguments);
});
Ответ 5
Попробуйте выполнить even.stopImmediatePropagation
в onclick
привязку к ссылке. Страница открывается и не выполняет обработчик.
var li = $("<li></li>")
.data("item.autocomplete", item)
.append('<a class="ac-item-a" href="#" onclick="location.href='http://www.nba.com'; return false;">' + item.label + '</a>')
.appendTo(ul);
li.find('a').bind('click', function(event){ event.stopImmediatePropagation() });
return li;