Метод jQuery html() автоматически объединяет аргумент, если он массив?

Во время экспериментов я столкнулся с этим.

<div id="result"></div>
<script type="text/javascript">
$('#result').html(['<p>This is inside an array</p>', '<em>This is second item in array</em>']);
</script>

Когда страница была прочтена, я мог видеть следующую разметку в консоли браузера:

<div id="result">
   <p>This is inside an array</p>
   <em>This is second item in array</em>
</div>

Означает ли это, что jQuery запускает array.join("") в фоновом режиме, если аргумент/параметр array.join("") в. Метод html() - это массив?

Я не мог найти это в документации, и поэтому было любопытно узнать об этом больше.

Ответ 1

Когда передано что-то другое, кроме строки, .html() .append() элемент и использует .append() для добавления HTML вместо этого, который при .append() массива вставляет строки HTML в массив в том порядке, в котором они появляются. Это поведение .append() только для .append().

Тот факт, что .html() использует .empty().append() внутри, когда передан аргумент, что ни строка, ни функция не указаны на странице документации. Ближайшим является утверждение о том, что jQuery опустошает элемент во многом таким же образом, когда ему задана функция, хотя это просто происходит по тому же пути .empty().append().

Обратите внимание, что это фактически не вызывает Array.join() так, как вы ожидали. Он добавляет элементы, представленные каждой строкой в массиве один за другим, вместо того, чтобы сначала присоединять все строки, прежде чем вставлять их через innerHTML. Так, например, следующее с отсутствующим (необязательным) </p> тегом end ведет себя одинаково - оно не вставляет p содержащего em child, а p и em качестве брака, в следующем порядке:

$('#result').html(
  [
    '<p>This is inside an array',
    '<em>This is second item in array</em>'
  ]
);

Ответ 2

Расширение ответа @BoltClock, определение метода html в файле jquery.js выглядит так:

html: function( value ) {
    return access( this, function( value ) {
        var elem = this[ 0 ] || {},
            i = 0,
            l = this.length;

        if ( value === undefined && elem.nodeType === 1 ) {
            return elem.innerHTML;
        }

        // See if we can take a shortcut and just use innerHTML
        if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
            !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {

            value = jQuery.htmlPrefilter( value );

            try {
                for ( ; i < l; i++ ) {
                    elem = this[ i ] || {};

                    // Remove element nodes and prevent memory leaks
                    if ( elem.nodeType === 1 ) {
                        jQuery.cleanData( getAll( elem, false ) );
                        elem.innerHTML = value;
                    }
                }

                elem = 0;

            // If using innerHTML throws an exception, use the fallback method
            } catch ( e ) {}
        }

        if ( elem ) {
            this.empty().append( value );
        }
    }, null, value, arguments.length );
},

Таким образом, это проверяет, if (typeof value === "string" и когда он терпит неудачу, он пропускает часть, непосредственно устанавливая значение как innerHTML и if(elem) выполняется после проверки того, что его element выполняет то, что указано в ответе @BoltClock. т.е.

this.empty().append( value );

и определение empty

// Remove all callbacks from the list
empty: function() {
       if ( list ) {
          list = [];
        }
        return this;
},