使用JQuery创建链接的最佳方法是什么?

27

我们在JQuery网格中使用jqGrid自定义格式化程序来输出链接。我们仅使用字符串操作构建链接,例如:

var s = "<a title=\"Blah\" href=\"javascript:BlahFunc('" + options.rowId + "')\">This is blah<a>";

有没有更加“聪明”的方式使用 JQuery 创建链接(以及其他表单元素)?

6个回答

113

我发现最好的是

$('<a>',{
    text: 'This is blah',
    title: 'Blah',
    href: '#',
    click: function(){ BlahFunc( options.rowId );return false;}
}).appendTo('body');

实时示例请移步http://www.jsfiddle.net/gaby/RhWgf/

我已经用附加的处理程序替换了行内JavaScript

引用来自有关jQuery()的文档

jQuery( html, props )

html 字符串定义单个、独立的HTML元素(例如<div/>或<div></div>)。
props 映射属性、事件和方法到新创建的元素。


更新

如果您想获取链接的实际文本,应将其包装在div中并返回其.html()

(或者:您可以使用原始元素的.outerHTML属性进行访问)

完整示例请移步http://www.jsfiddle.net/gaby/RhWgf/1/(已删除单击处理程序,因为它将在字符串版本中丢失,并用live处理程序代替,以针对特定类型的链接)


18

正如Steven Xu所正确提到的,插入HTML字符串比操作DOM更快,这就是为什么我建议使用字符串操作创建元素而不是jQuery。

您只需要更改这个:

var s = "<a title=\"Blah\" href=\"javascript:BlahFunc('" + options.rowId +
        "')\">This is blah<a>";

转换成这样:

var s = "<a title=\"Blah\" href=\"javascript:BlahFunc('" + options.rowId +
        "')\">This is blah</a>";

在字符串结尾处使用</a>标签来关闭<a>标签。

字符串操作比DOM操作快得多(例如,请参见此处)。此外,如果您尝试在大型HTML代码的中间插入DOM片段,差异将更大。使用DOM DocumentFragments可以略微提高性能,但字符串拼接是最快的方式。

所有其他答案都没有了解您使用它的上下文(jqGrid自定义格式化程序)。我尝试解释为什么这对您很重要。

由于性能优势,jqGrid首先将网格的HTML代码片段构建为字符串数组,然后使用.join('')将字符串数组构建为一个字符串,并将结果在表体末尾插入。(我假设您使用gridview:true jqGrid选项,这几乎总是推荐的)。jqGrid自定义格式化程序是jqGrid在构建网格(表)主体期间使用的回调函数。自定义格式化程序必须将HTML代码片段作为字符串返回结果。该字符串将与构建网格(表)主体的其他字符串连接。

因此,如果您将当前代码从纯字符串操作更改为jQuery DOM操作并将结果转换为字符串(需要作为自定义格式化的结果返回),则您的代码将变慢,并且您将没有其他优势*。

使用字符串操作的唯一真正缺点是构建代码时验证代码的问题。例如,使用没有关闭标签</a>的代码是可能出现问题的。在大多数情况下,在插入DOM片段期间会解决该问题,但有时您可能会遇到实际问题。因此,您应该非常仔细地测试您插入的代码。

另一个注释:如果您想遵循不显眼JavaScript风格,可以将“#”用作href属性的值,并在gridCompleteloadComplete事件处理程序内绑定相应的click事件。如果您在实现此功能时遇到问题,可以打开一个新问题,我将尝试为您编写相应的代码示例。

注意:我认为最好的实现方式将是使用onCellSelectbeforeSelectRow而不是在列中绑定click事件的每个<a>元素。我建议阅读以下答案以获取详细信息:此答案另一个答案另一个旧答案


2
插入HTML字符串比DOM更快 - 当然,这也是确保您有大量XSS问题的最佳方法。 - oreoshake
@oreoshake:抱歉,我不确定我是否正确理解了您的意思。我回答的问题是关于jqGrid自定义格式化程序的用法。这是jqGrid使用的回调函数,用于构造特定列中单元格的HTML内容。因此,自定义格式化程序必须返回字符串,因为这是jqGrid接口的要求。该要求存在是因为jqGrid将网格的所有行构建为一个字符串,并将其作为一个DOM操作插入。这提高了性能。 "Gaby aka G. Petrioli"的答案与问题无关,因为它不能与jqGrid一起使用 - Oleg

12
jQuery('<a>').attr('href', 'url').text('blah')

你可以使用 jQuery 创建一个对象,然后使用 .append 将其添加到 DOM 中。


有没有一种方法可以只返回原始的HTML?类似于jQuery('<a>').attr('href', 'url').text('blah').html()这样的东西? - Marcus Leon
我能够做到这一点的唯一方法就是将它附加到另一个 div 上并获取该 div 的 html,如下所示:jQuery('<div>').append(jQuery('<a>').attr('href', 'url').text('blah')).html()。.html 只会获取当前元素内部的内容,因此我不得不将其包装在其他东西中。但实际上,你在问题中提到的那种方式没问题。我以前用过 jQGrid,并且就是这样做的。 - shoebox639

9

好的,我之前是根据文章来写的,但我总是忘记需要加括号。 - TJB

1

一般来说,插入HTML字符串比多次DOM注入和DOM操作更快,这就是jQuery DOM操作的本质。如果您想要插入500个这样的元素,从性能上考虑,最好的选择是准备好HTML字符串,然后将其附加到文档中。

但对于您简单的需求,您当前的选项已经足够了。对于更聪明的做法,您可以在新元素上使用jQuery的DOM操作库。下面的示例应该很容易理解,但如果我在某个地方没有表达清楚,请留言,我会帮助您解决问题。

var toBeAdded = [
  { title: "one", row: 1, content: "ONE" },
  { title: "two", row: 2, content: "TWO" },
  { title: "three", row: 3, content: "THREE" }
];

var s = toBeAdded.length;
for(i=0;i<s;i++) {
  var a = $('<a>');
  a.attr('title', toBeAdded[i].title);
  a.attr('rel', toBeAdded[i].row);
  a.text(toBeAdded[i].content);
  a.addClass('blah_class');
  a.appendTo($('body'));
}

然后在你的通用脚本中:

$('a.blah_class').live('click', function(){
  var rel = $(this).attr('rel');
  BlahFunc(rel);
});

0

这是对我有帮助的,从按钮获取链接以获得新链接

var $jsClonedButtonLinkContainer = $('.js-cloned-button-link-container');
$jsClonedButtonLinkContainer.each(function() {
    $('<a>', {
      href: $(this).find('a.nectar-button').attr('href'),
      'class': 'flip-box__cloned-button-link'
    }).prependTo($(this).find('.flip-box-back'));
  });

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