Как повесить событие на кнопку, которая создана функцией?

Рейтинг: -1Ответов: 1Опубликовано: 01.08.2023

Как повесить событие на кнопку, которая создана функцией? Есть функция по созданию кнопки:

export function switchStorageBtn() {
  const btnSwap = document.createElement('button');
  btnSwap.textContent = 'Перейти на серверное хранилище';

  btnSwap.classList.add('btn', 'btn-info')
  btnSwap.style.marginBottom = '10px';

  btnSwap.dataset.storage = 'local';

  return btnSwap;
}

Затем я ее передаю в основной скрипт для того, чтобы потом повесить обработчик событий:

import { switchStorageBtn, loadLocalStorage, loadApiStorage } from './todo-app/switch-storage.js';
const btnSwitch = switchStorageBtn();

function loadStorage() {
  btnSwitch.addEventListener('click', () => {
     console.log(1);
  })
       
  loadApiStorage()
}

loadStorage();

Но обработчик событий не срабатывает, почему?

Дополнение:

Использую динамический импорт, чтобы подгружал код, когда мне нужно. Эти функции loadApiStorage и loadLocalStorage находятся в одном файле с функцией создания кнопки.

export async function loadApiStorage() {
  const { createTodoApp } = await import('./view.js');
  const {
    getTodoList,
    createTodoItem,
    switchTodoItemDone,
    deleteTodoItem
  } = await import('./api.js');
  const owner = 'myTasks';

  const todoItemList = await getTodoList(owner);
  createTodoApp(document.getElementById('todo-app'), {
    title: 'Мои дела',
    owner,
    todoItemList,
    onCreateFormSubmit: createTodoItem,
    onDoneClick: switchTodoItemDone,
    onDeleteClick: deleteTodoItem,
  })
}

export async function loadLocalStorage() {
  const { createTodoAppLocal } = await import('../todo-app.js');
  createTodoAppLocal(document.getElementById('todo-app'), 'Мои дела', 'myTasks');
}

Изначально я написал такой ивент:

btnSwap.addEventListener('click', () => {
    btnSwap.dataset.storage = (btnSwap.dataset.storage === 'local' ? 'api' : 'local');
    btnSwap.textContent = (btnSwap.dataset.storage === 'local' ? btnSwap.textContent = 'Перейти на серверное хранилище' : btnSwap.textContent = 'Перейти на локальное хранилище');
    btnSwap.dataset.storage === 'local' ? loadLocalStorage() : loadApiStorage();
    console.log(btnSwap.dataset.storage);
  })

Но по нажатию он добавляет новый контейнер со списком. Тогда я импортировал все функции из этого файла и в основном скрипте прописал условие

import { switchStorageBtn, loadLocalStorage, loadApiStorage } from'./todo-app/switch-storage.js';
  const btnSwitch = switchStorageBtn();

  function loadStorage() {
    if (btnSwitch.dataset.storage === 'local') {
      loadLocalStorage();
    } else {
      loadApiStorage()
    }
  }

  loadStorage();

Функции, где я добавляю кнопку, они разные, для апи:

async function createTodoApp (container, {
  title,
  owner,
  todoItemList = [],
  onCreateFormSubmit,
  onDoneClick,
  onDeleteClick,
}) {
  const todoAppTitle = createAppTitle(title);
  const todoItemForm = createTodoItemForm();
  const todoList = createTodoList();
  const todoBtnSwitch = switchStorageBtn();
  const handlers = { onDone: onDoneClick, onDelete: onDeleteClick };

  container.append(todoAppTitle, todoBtnSwitch, todoItemForm.form, todoList);

  todoItemList.forEach(todoItem => {
    const todoItemElement = createTodoItemElement(todoItem, handlers)
    todoList.append(todoItemElement)
  })

  todoItemForm.form.addEventListener('submit', async el => {
    el.preventDefault();

    if (!todoItemForm.input.value) {
      return;
    }

    const todoItem = await onCreateFormSubmit({
      owner,
      name: todoItemForm.input.value.trim(),
    });

    const todoItemElement = createTodoItemElement(todoItem, handlers);

    todoList.append(todoItemElement);
    todoItemForm.button.disabled = true;
    todoItemForm.input.value = '';
  })
}

export { createTodoApp };

Для локального:

function createTodoAppLocal (container, title = 'Список дел', keyTasks) {
  const todoAppTitle = createAppTitle(title);
  const todoItemForm = createTodoItemForm();
  const todoList = createTodoList();
  const btnSwitch = switchStorageBtn();

  listName = keyTasks;

  container.append(todoAppTitle, btnSwitch, todoItemForm.form, todoList);

  let localStorageData = localStorage.getItem(listName);
  if (localStorageData !== null && localStorageData !== '') {
    tasks = JSON.parse(localStorageData);
  }

  for (const itemArr of tasks) {
    let todoItem = createTodoItem(itemArr);
    todoList.append(todoItem);
  }

  todoItemForm.form.addEventListener('submit', async function (el) {
    el.preventDefault();

    if (!todoItemForm.input.value) {
      return;
    }

    const newTask = {
      id: getId(tasks),
      name: todoItemForm.input.value.trim(),
      done: false,
    }

    tasks.push(newTask);
    console.log(tasks);

    saveLocalStorage(tasks, listName);

    todoList.append(createTodoItem(newTask));
    todoItemForm.button.disabled = true;
    todoItemForm.input.value = '';
  })
}

export { createTodoAppLocal };

Ответы

▲ 1

Но обработчик событий не срабатывает, почему?

В примере нет собственно добавления созданной кнопки... Если такую кнопку добавить сразу после "навешивания" обработчика - все работает.

//
function switchStorageBtn() {
  const btnSwap = document.createElement('button');
  btnSwap.textContent = 'Перейти на серверное хранилище';
  btnSwap.classList.add('btn', 'btn-info')
  btnSwap.style.marginBottom = '10px';
  btnSwap.dataset.storage = 'local';
  return btnSwap;
}
const btnSwitch = switchStorageBtn();
//
function loadStorage() {
  btnSwitch.addEventListener('click', () => {
     console.log('ok');
  })
}
loadStorage();
// осталось только добавить на страницу...
document.querySelector('div').insertAdjacentElement('beforeend', btnSwitch)
<div></div>