JS - Как вернуть результат работы функции (RETURN), в которой цикл forEach и прослушиватель addEventListener

Есть форма с радио кнопками и чекбоксами.

Пытаюсь написать функцию, которая должна вернуть input, по которой нажали. Проверяю клик в консоли, все работает. Но вот return не могу сделать, чтобы вытащить из функции результат.

Как правильно это сделать?

const form = document.querySelectorAll("input[type='radio'],input[type='checkbox']");

function getLastСlickedInput() {
    form.forEach(function (input) {
        input.addEventListener('click', function() {
            // console.log(input); в консоль все выводит, по клику.
            return input;
        });
    });
}
getLastСlickedInput();

Ответы (3 шт):

Автор решения: Roman Kh

Ответ не работает из-за анонимной функции forEach.

<form action="">
    <input type="checkbox">
    <input type="radio">
    <p class="btn">click</p>
</form>
<script>
    let lastClickedInput = null;

    function getLastClickedInput() {
      const form = document.querySelectorAll("input[type='radio'],input[type='checkbox']");
      form.forEach(function (input) {
        input.addEventListener('click', function() {
          lastClickedInput = input; 
          console.log(input)
        });
      });
    }

    getLastClickedInput();

    document.querySelector('.btn').addEventListener('click', function() {
        console.log(lastClickedInput)
    })
</script>
→ Ссылка
Автор решения: Grundy

Так как неизвестно время нажатия - событие асинхронное.

Доступ к элементу есть только внутри обработчика. Если нужно только разовое действие - можно воспользоваться Pomise, если нужно что-то делать на каждое нажатие - единственный вариант передавать обработчик:

const form = document.querySelectorAll("input[type='radio'],input[type='checkbox']");

function getLastСlickedInput(cb) {
    form.forEach(function (input) {
        input.addEventListener('click', function() {
            cb(input);
        });
    });
}

getLastСlickedInput((input)=>{
    console.log(input);
});

альтернативный подход использовать observable, но суть с callback останется та же.

→ Ссылка
Автор решения: shaidullin2h

По-моему JS не возвращает значение из обработчика из-за асинхронного процесса. Можно создать переменную, которая будет сохранять последний кликнутый элемент и возвращать уже её.

После константы form объявите переменную со значением Null

let lastClickedInput = null;

в неё мы сохраним последний кликнувший элемент:

const form = document.querySelectorAll("input[type='radio'],input[type='checkbox']");
let lastClickedInput = null;  // Переменная для сохранения последнего кликнутого элемента

form.forEach(function (input) {
  input.addEventListener('click', function() {
    lastClickedInput = input;
    console.log(lastClickedInput);  // выводим последее кликнувшее зеначение в консоль
  });
});

function getLastСlickedInput() {
  return lastClickedInput;
}


const clickedInput = getLastСlickedInput();
console.log(clickedInput);  // вывод последнего прокликанного элемента в консоль

создав переменную lastClickedInput, которая обновляется при клике на элементе. Затем мы добавили новую функцию getLastСlickedInput(), которая возвращает значение lastClickedInput. Вы можете вызывать эту функцию в любом месте кода, чтобы получить последний кликнутый элемент. Надеюсь, я правильно вас понял, когда то давным давно сталкивался с подобным.

Как уже писали в ответах про callback. В моем первом примере getLastСlickedInput возвращает lastClickedInput до того, как оно ему присвоится. Попробуйте ещё такой вариант:

const form = document.querySelectorAll("input[type='radio'],input[type='checkbox']");
let lastClickedInput = null; // Переменная для сохранения последнего кликнутого элемента

form.forEach(function (input) {
  input.addEventListener('click', function() {
    lastClickedInput = input;
    console.log(lastClickedInput); // выводим последее кликнувшее зеначение в консоль
  });
});

function getLastСlickedInput(callback) {
  callback(lastClickedInput);
}

getLastСlickedInput(function(clickedInput) {
  console.log(clickedInput);
});

В этом примере, функция getLastСlickedInput принимает обратный вызов в качестве аргумента callback. После каждого клика, она вызывает этот обратный вызов и передает ему lastClickedInput. Вы можете определить свою логику внутри обратного вызова, когда значение clickedInput доступно.

→ Ссылка