【问题标题】:How does jQuery create DOM elements from string?jQuery 如何从字符串创建 DOM 元素?
【发布时间】:2017-06-29 16:26:45
【问题描述】:

我正在尝试从字符串创建一个元素,这是作为 Vue 组件实现的外部库(Bootcamp 的 Trix 编辑器)所必需的。 因此,我在Trix issues中发现了如下sn-p:

let _ = require('lodash');

Vue.component('wysiwyg', {
  props: ['value'],
  template: '<div></div>',

  data() {
    return {
      trix: null,
      id: ''
    }
  },

  mounted() {
    this.id = _.sampleSize('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 5).join('');

    this.trix = $(`<trix-editor input="${this.id}"></trix-editor>`);

    let self = this;

    this.trix.on('trix-change', (e) => {
      self.$emit('input', e.currentTarget.innerHTML)
    });

    this.$watch('value', function(value) {
      value = value === undefined ? '' : value;
      if (self.trix[0].innerHTML !== value) {
        self.trix[0].editor.loadHTML(value);
      }
    });

    this.trix.insertAfter(this.$el);
  },
});

他们使用 jQuery 来创建元素,我想避免这种情况。使用模板标签或 DOMParser,库将无法加载 - 但使用 $(template),一切正常。
以下 sn-ps 和如何正确处理有什么区别?

我尝试了几种失败的方法:

  1. createContextualFragment:

    let el = document
         .createRange()
         .createContextualFragment('<div class="foo"></div>')
    
  2. 带有模板标签:

    let template = document.createElement('template');
    template.innerHTML = '<div class="foo"></div>';
    let el = template.content.firstChild;
    
  3. DOMParser:

    let el = (new DOMParser())
         .parseFromString('<div class="foo"></div>', 'text/html')
         .body.childNodes[0];
    

以上所有方法都正确创建了元素,节点已插入 DOM,但编辑器库不会启动。

使用 jQuery,插入元素并启动编辑器库:

    let el = $('<div class="foo"></div>')

总而言之,我不是在寻找有关实现 Trix 库的建议,但我想知道 jQuery 在创建元素时有什么不同。

【问题讨论】:

  • 无论如何,jQuery 源代码都是现成的。您可以确切地看到他们是如何做到的。
  • 是的,我知道。我有时会查看代码片段以了解它们如何解决特定问题,但如果您不熟悉源代码结构,可以说很难阅读。

标签: javascript jquery vue.js


【解决方案1】:

基本上,jQuery 使用 RegExp 和其他技巧来解析字符串中的相关部分。对于您给出的示例,它将获得一个 div 类型的元素,其 class 属性的值为 foo

然后它使用该数据创建元素并添加与属性对应的属性:

var element = document.createElement("div");
element.className = "foo"; // className is the DOM property equivalent to the class attribute

这个特定的例子就是这样,因为该元素没有任何由 HTML 字符串指示的子元素

【讨论】:

  • 如果它有孩子呢?这会导致与我的一种本地方法不同的任何额外步骤吗?
  • @MoFriedrich 是的,对于每个子元素,递归调用创建元素需要的函数,然后将创建的子元素添加到带有appendChild()的元素
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 2011-02-11
  • 2012-04-13
  • 2012-05-22
  • 2020-01-14
  • 1970-01-01
  • 2012-03-24
相关资源
最近更新 更多