Эффективный метод вставки элементов jQuery в литералы шаблона - PullRequest
0 голосов
/ 18 декабря 2018

Занимаясь 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>`);

Я мог бы кропотливо создать внешний div, p, добавить p к div и добавитьот button до p.Это выглядит как неуклюжий шаблон.

Вместо этого я мог бы добавить button непосредственно к литералу шаблона:

<div><h1>Some content</h1><p>Press this button: <button>Click Me</button></p></div>

А затем find() it и связать обработчики, которыеКстати, это выглядит немного лучше, но мне все равно придется дать моему button уникальный id или class, чтобы иметь возможность find, в зависимости от контекста.Это также не "цепочка" хорошо, как, например, выше, добавление find() в конец моего const $ele = .. оператора приведет к $ele хранению button, а не div.Это нежелательно чаще, чем нет.

Итак, есть ли лучшее решение?

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

Давайте повеселимся с тегами литералов шаблона:

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>
0 голосов
/ 18 декабря 2018

Кажется, это горячая тема, поэтому, объединяя некоторые идеи здесь, это глупо?:

$.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 (текст, заголовки и т. Д.), Быть частью литерала шаблона
0 голосов
/ 18 декабря 2018

Вместо 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>
...