Буфер вывода Javascript размещает вещи в неправильном порядке

Мой обычный код javascript, похоже, выводит данные на страницу либо неправильно, либо в неправильном порядке, что странно, потому что код очень прост (возможно, максимум 20 строк). Мой код ниже. Примечание:

  • pttr_data.length вернет 150
  • clean_array.length вернет 4.
  • output — это объект div, т.е. var output = document.getElementById("results");

Я хочу, чтобы мой код выводился следующим образом:

<div>matcha matchb matchc matchn </div>

Но вместо этого он возвращает:

<div/>matcha matchb matchc match

Вот мой код, в который я поместил случайные символы, чтобы выяснить, куда что идет (вы увидите там ;;;, |||, [[[, }}} вокруг div):

var len = pttr_data.length;
for (var i = 0; i < len; i++) {
    var clean_array = pttr_data[i].match(RegExp(rexp.value, flags.value));
    output.innerHTML += ";;;<div>|||";
    var lengthy = clean_array.length;
    for (var j = 1; j < lengthy; j++) {
        if( clean_array[j] ) { output.innerHTML += clean_array[j] + ' '; }
        else { output.innerHTML += 'NULL '; }
    }
    out.innerHTML += "[[[</div>}}}\n";
}

Этот код возвращает:

;;;<div>|||</div>matcha matchb matchc [[[}}}

Может кто-нибудь объяснить, почему это происходит? Циклы javascript for работают независимо (и, следовательно, заканчиваются с разной скоростью), даже если они вложены друг в друга? Хотя это не имеет смысла, зачем кому-то разрабатывать такой язык сценариев?
Как мой код мог выводить <div/>blah вместо <div>blah</div> ?

Спасибо


person stoicfury    schedule 01.03.2012    source источник


Ответы (1)


Свойство .innerHTML немного сложнее, чем просто строка, к которой можно добавить. Если вы добавите к нему "<div>" (или ";;;<div>|||" в вашем примере), браузер не будет ждать, чтобы увидеть, добавите ли вы в конечном итоге закрывающий тег </div>, он просто немедленно создаст div. Затем вы добавляете дополнительный текст: "matcha", "matchb", etc. И, наконец, вы добавляете закрывающий </div>, который браузер игнорирует, потому что, опять же, он его не ждал, но сохраняет "[[[}}}".

Вместо добавления к .innerHTML по ходу дела добавьте к строковой переменной, а затем установите .innerHTML равным этой строке в конце.

Если вы хотите добавить все элементы clean_array, разделенные пробелами, вам даже не нужен цикл for, вы можете просто использовать .join():

output.innerHTML = "<div>" + clean_array.join(" ") + "</div>";
// or for all from index 1
output.innerHTML = "<div>" + clean_array.slice(1).join(" ") + "</div>";

Но чтобы сохранить вложенный цикл for:

var len = pttr_data.length,
    outputStr = "";  // use a string variable

for (var i = 0; i < len; i++) {
    var clean_array = pttr_data[i].match(RegExp(rexp.value, flags.value));
    outputStr += ";;;<div>|||";
    var lengthy = clean_array.length;
    for (var j = 1; j < lengthy; j++) {
        // I think ternary conditional is neater than if/else
        outputStr += clean_array[j] ? clean_array[j] + ' ' : 'NULL ';
    }
    outputStr += "[[[</div>}}}\n";
}

output.innerHTML += outputStr;
person nnnnnn    schedule 01.03.2012