Как можно одновременно получать данные из одного callback и передавать их в другой?

Добрый день. <br/> <br/> У меня есть следующий код: <br/> <br/> <pre><code class="javascript">function box(nameBlock, options, callback) {
        var code = options.code ? options.code : [];
        var inputs = [];
        var currentBlock = document.querySelector('#' + nameBlock);

        for (var i = 0; i &lt; code.length; i++) 
            if (code[i] == nameBlock) {
                currentBlock.innerHTML = callback();

                for (var j = 0; j &lt; currentBlock.querySelectorAll('input').length; j++) inputs.push(currentBlock.querySelectorAll('input')[j].getAttribute('name'));

                callback(null, null, inputs);
            }
    }</code></pre> <br/> <br/> А вот как он используется: <br/> <br/> <pre><code class="javascript">box('test', {}, function(error, result, page){
        return '&lt;div&gt;Auth&lt;/div&gt;&lt;br&gt;&lt;input name="login" placeholder="Enter login"&gt;&lt;br&gt;&lt;input name="password" placeholder="Enter password"&gt;';
    });</code></pre> <br/> <br/> Основная задача — отправить HTML-код через return обратно в функцию, чтобы он корректно отображался на странице. Однако, у меня есть необходимость передать информацию об inputs из блока в переменную page и использовать их результаты в разметке до отправки в return. Проблема в том, что доступ к inputs возможен только после вставки кода из return, так как в этот момент они еще не добавлены в разметку. В результате, при попытке получить доступ к inputs сначала возвращается undefined, а затем уже получаются данные inputs, которые нельзя использовать. <br/> <br/> Вопрос — возможно ли как-то извлечь разметку из...
  • 15 февраля 2025 г. 11:35
Ответы на вопрос 2
Да, вы можете решить эту задачу, изменив подход к обработке HTML-кода и получения данных из элементов формы. Вместо того чтобы пытаться получить данные о полях ввода сразу после вставки кода, вы можете сначала создать временный элемент, в который будет помещен ваш HTML, а затем извлекать из него необходимые значения. Это позволит вам избежать проблемы с попыткой доступа к элементам, которые еще не добавлены в документ.

Вот обновленный код на основе вашего, который решает вашу проблему:

```javascript
function box(nameBlock, options, callback) {
    var code = options.code ? options.code : [];
    var currentBlock = document.querySelector('#' + nameBlock);
    
    for (var i = 0; i < code.length; i++) {
        if (code[i] == nameBlock) {
            // Получаем HTML-код из callback
            var html = callback();
            
            // Создаем временный элемент для парсинга HTML
            var tempDiv = document.createElement('div');
            tempDiv.innerHTML = html;

            // Вставляем HTML-код в текущий блок
            currentBlock.innerHTML = tempDiv.innerHTML;

            // Теперь получаем все input-поля
            var inputs = [];
            var inputElements = currentBlock.querySelectorAll('input');

            for (var j = 0; j < inputElements.length; j++) {
                inputs.push(inputElements[j].getAttribute('name'));
            }

            // Передаем полученные данные в callback
            callback(null, null, inputs);
        }
    }
}

// Пример использования
box('test', {}, function(error, result, page) {
    return '<div>Auth</div><br><input name="login" placeholder="Enter login"><br><input name="password" placeholder="Enter password">';
});
```

### Что изменилось:

1. **Создание временного элемента:** Мы создаем элемент `div`, чтобы временно хранить HTML-код, который возвращает ваш callback. Это позволяет безопасно работать с ним без необходимости напрямую вставлять его в документ сразу.

2. **Извлечение input-полей:** После вставки HTML-кода из временного элемента в `currentBlock`, мы можем безопасно извлекать имена input-полей, так как они уже были добавлены в разметку.

Таким образом, вы получаете возможность сначала подготовить HTML и потом извлечь информацию о полях ввода, а полученные данные можно передать обратно в callback или использовать по вашему усмотрению.
Вот в таких ситуациях я понимаю, зачем придумали VueJS )). 
А если решить задачу в рамках существующего стека, то где-то тут нужно прервать поток выполнения JS функцией setTimeout с нулевым временем ожидания, и продолжить работать с инпутами внутри вызываемой функции setTimeout. Это позволит передать управление браузеру, чтобы он успел отрисовать то, что закинуто в DOM через innerHTML:
if (code[i] == nameBlock) {
                currentBlock.innerHTML = callback();
                setTimeout(function(currentBlock, inputs)
     {
  
for (var j = 0; j < currentBlock.querySelectorAll('input').length; j++) inputs.push(currentBlock.querySelectorAll('input')[j].getAttribute('name'));

                callback(null, null, inputs);
}, 0, // нулевое время setTimeout
currentBlock, inputs // проверьте, чтобы правильно передавались аргументы внутрь setTimeout
);
        break; // тут, наверное, можно прерывать внешний цикл, раз нашли нужное
            }
Похожие вопросы