在<a> elements that are programmatically added to a DOM</a>上捕获点击事件

时间:2010-08-21 01:59:14

标签: javascript jquery dom javascript-events

我有一个AJAX回调,它返回一个结果列表,这些结果写在特定div内的链接中。代码如下:

$.each(data, function (idx, item) {
    var a = document.createElement("a");
    a.innerText = item.name;
    a.href = "#";
    // TODO set handler for click event
    d.appendChild(a);
    d.innerHTML += "<br/>";
});

此工作正常,并显示链接。但是,我想在单击链接时执行某些操作。 item在点击处理程序中有一些其他属性,所以我想关闭它们。这是处理程序的定义:

    // defined in loop as a closure
    var clickHandler = function() {
        $('#siteId').value = item.siteId; // closed over this property
        $('#siteName').value = item.name; // and this one
        return false;
    };

我尝试了一些为click事件提供此处理程序的方法。首先:

    a.onclick = clickHandler;

其次:

    a.addEventListener("click", clickHandler, true);  

我还尝试了mouseupmousedown个事件,但它们也没有用。

我看到的行为是浏览器导航到#锚点(它附加到URL)。

这里发生了什么?此外,是否有一个jQuery解决方案在浏览器中更强大?

4 个答案:

答案 0 :(得分:2)

你可以使用jQuery做这样的事情:

$.each(data, function (idx, item) {
  $("<a />", { text: item.name, href: '#', click: clickHandler })
     .appendTo(d).after('<br />');
});

这使用$(html, props)作为元素的创建方法,设置文本和href属性并在创建时分配点击处理程序。在此之后,我们使用.appendTo()将其添加到d元素,然后使用.after()添加<br />

答案 1 :(得分:2)

d.innerHTML += "<br/>";

那是你的问题。 从未 innerHTML+= 任何。它的作用是将父元素中的文档对象序列化为HTML,添加字符串,然后将整个字符串解析回新的DOM对象。这很慢,并且丢失了无法存储在序列化HTML标记中的所有信息,如字段值,JS引用和事件处理程序。因此,您在<a>上添加的任何事件处理程序都会被下一行立即销毁。

HTML不是浏览器中页面数据的最终存储;你不能直接编辑它。您只能将部分文档内容序列化为新的HTML(可能看起来与您在解析页面时放入的HTML一样),并将HTML解析为全新的对象。

相反,继续使用DOM方法:

d.appendChild(document.createElement('br'))

除了:

a.innerText = item.name;

这是一个在任何地方都不受支持的IE扩展。您可以将其用作不支持标准textContent属性的IE的后备,或者为了获得最大兼容性,只需使用普通的document.createTextNode()并将其附加到a

由于您似乎正在使用jQuery,因此请使用text()执行此操作,并使用click()绑定事件,与其他答案一样。

答案 2 :(得分:1)

  

是否有一个jQuery解决方案在浏览器中更强大?

您可以从现有DOM元素获取jQuery对象,然后以标准方式绑定click处理程序:

$(a).click(clickHandler);

另外,我怀疑你的点击处理程序本身是不正确的。如果您尝试设置元素的值,则应该使用val方法,而不是分配给value属性:

var clickHandler = function() {
    $('#siteId').val(item.siteId); // closed over this property
    $('#siteName').val(item.name); // and this one
    return false;
};

答案 3 :(得分:0)

使用jQuery.live将事件处理程序附加到现在或将来与选择器匹配的所有事件。请参阅jQuery文档:

http://api.jquery.com/live/

这将正确附加处理程序,即使在定义事件处理程序之后将元素添加到DOM