Which is the correct or better way to create a new element with jQuery?

后端 未结 4 1768
名媛妹妹
名媛妹妹 2021-02-05 19:48

Related to the answer https://stackoverflow.com/a/10619477/1076753 to cleate an element is better to use

$(\"
\", {id: \"foo\", class: \"a\"});
4条回答
  •  没有蜡笔的小新
    2021-02-05 20:28

    taking a look into the jQuery library, the following is the relevant section from v2.2.0 line 2827.

    init = jQuery.fn.init = function(selector, context, root) {
        var match, elem;
    
        // HANDLE: $(""), $(null), $(undefined), $(false)
        if (!selector) {
          return this;
        }
    
        // Method init() accepts an alternate rootjQuery
        // so migrate can support jQuery.sub (gh-2101)
        root = root || rootjQuery;
    
        // Handle HTML strings
        if (typeof selector === "string") {
          if (selector[0] === "<" &&
            selector[selector.length - 1] === ">" &&
            selector.length >= 3) {
    
            // Assume that strings that start and end with <> are HTML and skip the regex check
            match = [null, selector, null];
    
          } else {
            match = rquickExpr.exec(selector);
          }
    
          // Match html or make sure no context is specified for #id
          if (match && (match[1] || !context)) {
    
            // HANDLE: $(html) -> $(array)
            if (match[1]) {
              context = context instanceof jQuery ? context[0] : context;
    
              // Option to run scripts is true for back-compat
              // Intentionally let the error be thrown if parseHTML is not present
              jQuery.merge(this, jQuery.parseHTML(
                match[1],
                context && context.nodeType ? context.ownerDocument || context : document,
                true
              ));
    
              // HANDLE: $(html, props)
              if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
                for (match in context) {
    
                  // Properties of context are called as methods if possible
                  if (jQuery.isFunction(this[match])) {
                    this[match](context[match]);
    
                    // ...and otherwise set as attributes
                  } else {
                    this.attr(match, context[match]);
                  }
                }
              }
    
              return this;
    

    You will see that it checks if the selector is a string, and if it does then see's if it starts with < and ends with >.

    if (typeof selector === "string") {
      if (selector[0] === "<" &&
        selector[selector.length - 1] === ">" &&
        selector.length >= 3) {
    

    Then, having in mind the regex rsingleTag being:-

    var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
    

    Which matches both "

    " and "
    ", returning div as group[1].

    The parseHTML uses that to return a div element, in the merge:-

    jQuery.parseHTML = function( data, context, keepScripts ) {
    
        ...
    
        var parsed = rsingleTag.exec( data );
    
        // Single tag
        if ( parsed ) {
            return [ context.createElement( parsed[ 1 ] ) ];
        }
    

    then using the regex again, and context as your object for setting the properties:-

    // HANDLE: $(html, props)
    if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
    

    it for's over each property setting with this.attr(match, context[match]);

    So, at the end it's wrong to use one of the first two options for a div?

    As above shows, its personal preference. Both work the same.

提交回复
热议问题