Подтвердить что ты не робот

Функция Javascript работает неожиданным образом

У меня есть функция javascript 'doAll', которая должна писать весь текст, который был помещен между тегами <p>, </p>. В моем коде он используется двумя способами.

Он работает правильно, когда я просто вызываю его в конце страницы. Однако он также должен срабатывать при возникновении события кнопки клика. По какой-то причине он не делает то, что он должен делать в этот раз. Когда один щелчок на кнопке, он просто печатает внутренний html самого первого элемента <p>...</p> html.

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

<!DOCTYPE html>
<html>
    <head>
        <script>
            function returnList(x)
            {
                return document.getElementsByTagName(x);
            }

            function writeList(x)
            {
                var i = 0;

                while (x[i])
                {
                    document.write(x[i++].innerHTML + '<br/>');
                }
            }

            function doAll(x) 
            {
                writeList(returnList(x));
            }
        </script>
    </head>

    <body>
        <p>XXX</p>
        <p>YYY</p>
        <div style = 'background-color: gray;'>
            <p>YYY</p>
            <p>XXX</p>
        </div>

        <button type = 'button' onclick = "doAll('p')">
            Click me!
        </button>

        <script>
            document.write('<br/>');
            doAll('p');
        </script>
    </body>
</html>

Вот "выход":
XXX
YYY
YYY
XXX

XXX
YYY
YYY
XXX

И вот что можно увидеть после нажатия кнопки:
XXX

4b9b3361

Ответ 1

Проблема заключается в том, что страница уже отображается, когда вы нажимаете кнопку. Запуск document.write() в этот момент переопределит весь документ. Он записывает первый элемент, потому что это единственный элемент, который все еще существует, когда вы запускаете свою функцию. Любой другой элемент просто не будет присутствовать после выполнения document.write() в первый раз.

Даже сама ваша функция больше не будет частью документа. Если вы MUST работаете с document.write() или просто хотите использовать его для тестирования, вам нужно как-то "кэшировать" ваши данные и выводить их сразу:

function writeList(x) {
    var i = 0, data = "";

    while (x[i]) {
        data += x[i++].innerHTML + '<br/>';
    }

    document.write(data);
}

Ответ 2

document.write способен записывать контент только в документ, который в настоящее время загружается. После загрузки он ведет себя по-другому - см. https://developer.mozilla.org/en-US/docs/Web/API/document.write. Используйте специальный контейнерный элемент и innerHTML, чтобы записать желаемый результат.

function writeList(list) {
    var i, result = "";
    for (i = 0; i < list.length; i++) {
        result += list[i].innerHTML + "<br />";
    }
    document.getElementById("myContainer").innerHTML = result;
}

http://jsfiddle.net/3yPAW/1/

Ответ 3

В двух других ответах объясняется почему, я предлагаю вам как избежать этого:

добавьте свой HTML в innerHTML тела (или другого элемента);

вместо

document.write(x[i++].innerHTML + '<br/>');

использование

document.getElementsByTagName("body")[0].innerHTML += x[i++].innerHTML + '<br/>';

Демо: http://jsfiddle.net/MNCbx/