使jQuery自动完成中的<a>可点击

26

我使用以下代码成功地在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。唯一打开链接的方法是单击中间滚轮或右键并选择“在新标签页中打开”。
我尝试在链接上附加一个click事件处理程序,并使用event.stopImmediatePropagation(),但似乎不起作用。有没有人知道如何解决这个问题?

没有人知道这个吗? - pinghsien422
你正在使用jQuery自动完成或其他自动完成插件吗? - Leeish
你能提供一个使用数组而不是服务器响应的fiddle吗? - Gonzalo.-
5个回答

23

有一种方法是通过定义自定义的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


1
很棒的解决方案 - 可以使用更多的CSS样式来澄清这里正在发生什么。我建议您将JSFiddle编辑为此链接:http://jsfiddle.net/sqsinger/jkukvpgo/3/ - sqsinger
@sqsinger - 感谢您的样式,我已经编辑了答案并添加了您的fiddle。 - Amir Popovich
很好的想法,但为什么不让原生元素发挥作用呢?只需创建一个普通的超链接。没有任何黑客技巧,并且可以被辅助技术访问:http://jsfiddle.net/ryanwheale/jkukvpgo/6/ - Ryan Wheale
@RyanWheale - 因为单击超链接会选择当前项目,而这正是他想要避免的。 - Amir Popovich

5

您是否考虑在单击处理程序中放置一个条件,以便在该链接时不要preventDefault? 如果测试元素是否应正常运行,则可以在preventDefault之前尽早return,然后链接应该正常工作。

这里是一个例子(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

Amir,关于你的回答,我认为在select事件中从javascript函数打开窗口可能会被弹出窗口拦截器阻止。

pinghsien422,你的服务器端应该返回Json而不是完整的html,如果你必须返回完整的html,请进行以下更改:

1.删除clientSelect函数

2.renderData函数中不需要'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);
};

3

好的,jQuery 的事件优先于您的选择事件 - 无论您做什么,都无法停止任何操作。但是您可以代理菜单选择事件,然后决定是否调用它(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);
});

1
尝试在链接的onclick绑定中使用even.stopImmediatePropagation。页面会打开,但选择处理程序不会执行。请保留HTML标签。
var li = $("<li></li>")
    .data("item.autocomplete", item)
    .append('<a class="ac-item-a" href="http://www.nba.com">' + item.label + '</a>')
    .appendTo(ul);

li.find('a').bind('click', function(event){ event.stopImmediatePropagation() });

return li;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接