【问题标题】:Event listener fires 2 functions at the same time but partially事件侦听器同时触发 2 个函数但部分触发
【发布时间】:2021-10-05 15:09:59
【问题描述】:

我正在制作一个列表,您可以在其中编辑或删除项目。我正在同一张桌子上听 2 个事件。一个用于编辑,一个用于删除,我正在听表格而不是实际按钮,因为它们是动态创建的。 Edit 和 Delete 都具有相同的 id,即产品的 id,我稍后将其用于 http 请求。 , 现在,当我按下编辑时,删除功能中的 console.logs 会启动,但没有任何反应,如果我试图保存项目,http 请求不起作用,它不会使用 id(但会将其记录到控制台)

如果我按下删除按钮一次没有发生任何事情,如果我第二次按下它,页面会刷新并删除项目。

有没有办法单独监听这些事件或让它们不相互干扰?我想要的只是如果我按下编辑按钮将相应项目的值转到输入字段,当我按下添加项目时也更新 JSON 文件中的产品,并在删除按下时从 JSON 文件中删除项目和从 html 文档中删除。

更新:设法解决编辑功能

这是我的代码:

import { http } from "./http.js";
import { ui } from "./ui.js";

const productsURL = "https://61363d1a8700c50017ef54c1.mockapi.io/product";
// const addProductBtn = document.querySelector('.new-product-btn');
const adminContainer = document.querySelector('.admin-container');
const addItem = document.querySelector('.admin-add-item-btn');
const imgInput = document.getElementById('image');
const nameInput = document.getElementById('name');
const priceInput = document.getElementById('price');
const stockInput = document.getElementById('stock');
const categoryInput = document.getElementById('category');
const typeInput = document.getElementById('type');
const descriptionInput = document.getElementById('description');
const validSvg = document.querySelectorAll('.valid_input_svg');
// const adminForm = document.getElementById('admin-form');
const adminTable = document.getElementById('admin-tbody');
const editBtn = document.querySelectorAll('.edit-btn');
const adminBtn = document.querySelectorAll('.admin-delete-btn');
const cancel = document.getElementById('cancel');
let productToEdit;
let edit = false;
let id;


document.addEventListener('DOMContentLoaded', listAdminProducts);


// adminForm.addEventListener('submit', validateInput);
addItem.addEventListener('click', addOrEditProducts);
// adminTable.addEventListener('click', editOrDeleteItem);
adminTable.addEventListener('click', deleteProduct);
adminTable.addEventListener('click', editProduct);
cancel.addEventListener('click', cancelEdit);

function listAdminProducts() {
    http.get(productsURL).then(products => {
        ui.showAllAdminProducts(products);
    });
};


function addOrEditProducts() {
    if (edit === true && validateInput() === true) {
        productToEdit = {
            image: imgInput.value,
            name: nameInput.value,
            price: priceInput.value,
            stock: stockInput.value,
            category: categoryInput.value,
            type: typeInput.value,
            description: descriptionInput.value,
        };
        http
            .put(`${productsURL}/${id}`, productToEdit)
            .then(() => listAdminProducts());
        console.log(`${productsURL}/${id}`)
        ui.clearFields();
        id = '';
        edit = false;
        return;
    } else if (edit === false && validateInput() === true) {
        const product = {
            image: imgInput.value,
            name: nameInput.value,
            price: priceInput.value,
            stock: stockInput.value,
            category: categoryInput.value,
            type: typeInput.value,
            description: descriptionInput.value
        };
        http.post(productsURL, product).then(() => listAdminProducts());
        ui.clearFields();
    };
};

function editProduct(e) {
    console.log('works');
    if (e.target.classList.contains('edit-btn')) {
        edit = true;
        id = e.target.getAttribute('id');
        console.log(id);
        console.log(e.target)
        http.get(`${productsURL}/${id}`).then((data) => {
            imgInput.value = data.image;
            nameInput.value = data.name;
            priceInput.value = data.price;
            stockInput.value = data.stock;
            categoryInput.value = data.category;
            typeInput.value = data.type;
            descriptionInput.value = data.description;
        });
        console.log(`${productsURL}/${id}`)
    };
    // id = '';
}

function deleteProduct(e) {
    console.log(e.target);
    if (e.target.className === 'admin-delete-btn') {
        console.log(e.target);
        id = e.target.getAttribute('id');
        console.log(id);
        http
            .delete(`${productsURL}/${id}`)
            .then(() => listAdminProducts())
            .catch("Error on delete");
        id = '';
    }
    ui.showSuccessMessage('Product deleted', adminContainer);
}

function cancelEdit() {
    ui.clearFields;
    imgInput.className = '';
    nameInput.className = '';
    priceInput.className = '';
    stockInput.className = '';
    categoryInput.className = '';
    edit = false;
}


function validateInput() {
    let valid = true;
    if (imgInput.value == '') {
        if (imgInput.classList.contains('input-invalid')) {
            imgInput.classList.remove('input-invalid');
        };
        ui.showAdminMessage('Must contain a link to an image', 0);
        imgInput.classList.add('input-invalid');
        valid = false;
    } else {
        imgInput.classList.add('input-valid');
        validSvg[0].style.display = "block";
        removeClass(imgInput, 0);
    };

    if (nameInput.value === '') {
        if (nameInput.classList.contains('input-invalid')) {
            nameInput.classList.remove('input-invalid');
        };
        ui.showAdminMessage('Name is requierd', 1);
        nameInput.classList.add('input-invalid');
        valid = false;
    } else {
        // stockInput.classList.remove('input-invalid');
        nameInput.classList.add('input-valid');
        validSvg[1].style.display = "block";
        removeClass(nameInput, 1);
    };

    if (priceInput.value == "" || isNaN(priceInput.value) || priceInput.value < 0) {
        if (priceInput.classList.contains('input-invalid')) {
            priceInput.classList.remove('input-invalid');
        };
        ui.showAdminMessage('Price must be a number greater then 0', 2);
        priceInput.classList.add('input-invalid');
        valid = false;
    } else {
        // stockInput.classList.remove('input-invalid');
        priceInput.classList.add('input-valid');
        validSvg[2].style.display = "block";
        removeClass(priceInput, 2);
    };

    if (stockInput.value == "" || isNaN(stockInput.value) || stockInput.value < 0) {
        if (stockInput.classList.contains('input-invalid')) {
            stockInput.classList.remove('input-invalid');
        };
        ui.showAdminMessage('Stock must be a number greater then 0', 3);
        stockInput.classList.add('input-invalid');
        valid = false;
    } else {
        // stockInput.classList.remove('input-invalid');
        stockInput.classList.add('input-valid');
        validSvg[3].style.display = "block";
        removeClass(stockInput, 3);
    };

    if (categoryInput.value === 'barware' || categoryInput.value === 'spirits') {
        // categoryInput.classList.remove('input-invalid');
        categoryInput.classList.add('input-valid');
        validSvg[4].style.display = "block";
        removeClass(categoryInput, 4);
    } else {
        ui.showAdminMessage('Category must be barware or spirits', 4);
        categoryInput.classList.add('input-invalid');
        valid = false;
    };
    return valid;
};

function removeClass(element, index) {
    // console.log(element, index);
    setTimeout(() => {
        element.className = '';
        validSvg[index].style.display = "none";
    }, 3000)
}

【问题讨论】:

  • 嗯,您是否意识到您在 if 语句之外还有代码?就像ui.showSuccessMessage('Product deleted', adminContainer);不管你是否点击删除按钮都会运行。
  • 退出function deleteProduct(e) { if (!e.target.closest('.admin-delete-btn')) return;
  • Edit 和 Delete 都具有相同的 id。 ID 应该是唯一的。您应该将产品 ID 放在 data-XXX 属性中。
  • 是的,我知道它们具有相同的 id,它们具有产品的 id,我在 http 请求中使用它,但它们在函数中被重置。我将尝试将 id 放在数据值属性中

标签: javascript json function httprequest eventhandler


【解决方案1】:

终于设法解决了,我不得不把 e.preventDefault() 放在两个函数中,所以页面不会先重新加载

【讨论】:

    猜你喜欢
    • 2015-12-18
    • 2020-09-06
    • 2023-03-11
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多