在模板文字中插入jQuery元素的有效方法

时间:2018-12-18 19:51:46

标签: javascript jquery dom template-literals

在jQuery中,我经常遇到一个尴尬的情况。假设我想构造一个很大的HTML块,中间用jQuery包裹元素。我希望能够使用模板文字来做HTML,然后有效地放入jQuery包装的元素,以避免编写大量JavaScript代码来在树中分别构建每个元素。

例如,说我想在所述位置插入一个按钮:

const $btn = $(`<button>Click Me</button>`).click(() => { /* complex handler... */ });
const $ele = $(`<div><h1>Some content</h1><p>Press this button: [button should go here]</p></div>`);

我可以费力地创建外部divp,将p附加到div,并将button附加到{{1 }}。感觉好像很笨拙。

相反,我可以将p直接添加到模板文字中:

button

然后<div><h1>Some content</h1><p>Press this button: <button>Click Me</button></p></div> 并以这种方式绑定处理程序-似乎更好一些,但是我仍然必须给我的find()一个唯一的button或{{ 1}},以便能够id,具体取决于上下文。它也不能很好地“链接”,例如,在我的class语句末尾加上find会导致find()存储const $ele = ..,而不是$ele。这经常是不希望的。

那么,有没有更好的解决方案?

3 个答案:

答案 0 :(得分:2)

让我们来看看带有标记的模板文字的乐趣:

const $btn = jQuery(`<button>Click Me</button>`).click(e => alert("complex handler…"));
const $ele = $`<div><h1>Some content</h1><p>Press this button: ${$btn}</p></div>`;
//           ^^                                                ^^^^^^^          ^
jQuery("body").append($ele);

function $(parts, ...args) {
  const uid = Math.round(Math.random()*0xFFFF).toString(16).padStart(4, "0");
  const res = jQuery(parts.reduce((html, p, i) => {
    return html + "<slot name=x-replace-"+uid+"></slot>" + p;
  }));
  res.find("slot[name=x-replace-"+uid+"]").replaceWith(i => args[i]);
  return res;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

答案 1 :(得分:0)

您可以find() find()元素并将按钮附加到该元素上,而不是用字符串p对其添加属性。这样,就像您提到的另一种情况一样,不需要id

const $btn = $("<button>Click Me</button>").click(() => { /* complex handler... */ });
const $ele = $("<div><h1>Some content</h1><p>Press this button: </p></div>");
$ele.find("p").append($btn)

//This line is only for testing:
$ele.appendTo(document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

答案 2 :(得分:0)

似乎这是一个热门话题,所以结合这里的一些想法,这很愚蠢吗?:

$.fn.extend({
    swapIn: function (toSwap) {
        Object.entries(toSwap)
            .forEach(([k, $v]) => this.find(`[data-swap="${k}"]`).replaceWith($v));
        return this;
    }
});

const $btn1 = $(`<button>Click Me</button>`).click(() => { /* complex handler... */ });
const $btn2 = $(`<button>Don't Click Me</button>`).click(() => { /* complex handler... */ });
const $ele = $(`<div><h1>Some content</h1><p>Press this button: <div data-swap="$btn1"/> but not this button: <div data-swap="$btn2"/></p></div>`)
    .swapIn({$btn1, $btn2});

console.log($ele[0].innerHTML); // the desired resut, while keeping the jQuery objects handy for further manipulation

满足以下条件:

  • 易于使用/最小沸腾板
  • 易于阅读(我认为)-可以从上至下阅读
  • 友善链
  • 维护jQuery对象
  • 允许不需要的任何内容都必须是jQuery可访问的(文本,标头等),才能成为模板文字的一部分