You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将leaveDetails动态传递给事件处理器,避免重复绑定事件

问题描述

我希望将传入setLeaveDetails函数的leaveDetails传递给事件处理器,无需在setLeaveDetails函数中反复为leaveAccept和leaveDecline按钮添加或移除事件。请问能否使用currentLeaveDetails这类全局变量来实现,或者有其他可行方案?


HTML代码

<div id="leaveDetailsBox">
    <div class="smallHeading" id="leaverSeekerHeading">
        leave request details
    </div>
    <div class="leaveRequestInformation">
        <div class="SingleInfo">
            <p class="infoTitle">leave seeker name</p>
            <p class="infoDescription" id="leaveSeekerName"></p>
        </div>
        <div class="SingleInfo">
            <p class="infoTitle">no. of days</p>
            <p class="infoDescription" id="noOfDaysOfLeave"></p>
        </div>
        <div class="SingleInfo">
            <p class="infoTitle">status</p>
            <p class="infoDescription" id="leaveStatus">
                pending
            </p>
        </div>
        <div class="SingleInfo">
            <p class="infoTitle">reason</p>
            <p class="infoDescription" id="leaveReason">
                Amritpal Singh sidhu
            </p>
        </div>
        <div class="SingleInfo d-none">
            <p class="infoTitle">leave Decline reason</p>
            <p class="infoDescription" id="leaveDeclineReason"></p>
        </div>
        <div class="action" id="leaveRequestAction">
            <button id="acceptBtn">approve</button>
            <button id="declineBtn">Decline</button>
        </div>
    </div>
</div>

JavaScript代码

let leaveAcceptBtn = document.querySelector("#acceptBtn");
let leaveDeclineBtn = document.querySelector("#declineBtn");
function setLeavesDetails(leaveDetails) {
    leaverSeekerHeading.textContent = `${leaveDetails.leaveSeekerName}'s leave request details...`;
    leaveSeekerName.textContent = leaveDetails.leaveSeekerName;
    leaveReason.textContent = leaveDetails.leaveReason;
    leaveStatus.textContent = leaveDetails.status;
    leaveReason.textContent = leaveDetails.reason;
    if (leaveDetails.status !== "pending") {
        leaveRequestAction.classList.add("hide");
    } else {
        leaveRequestAction.classList.remove("hide");
    }
}
let declineHandler = (leaveDetails) => {
    Swal.fire({
        title: "Are you sure to decline leave?",
        icon: "question",
        input: "text",
        inputPlaceholder: "Enter leave reason(If Any)",
        showCancelButton: true,
        showCloseButton: true,
        showConfirmButton: true,
        confirmButtonText: "Decline",
        confirmButtonColor: "#eb5353",
        cancelButtonText: "Cancel",
        customClass: {
            title: "custom-title",
            icon: "custom-icon",
            confirmButton: "custom-confirm-button",
            cancelButton: "custom-cancel-button",
        },
    }).then((response) => {
        if (response.isConfirmed) {
            console.log(response.value);
            if (response.value.trim().length != 0 && response.value != " ") {
                updateLeaveStatus(leaveDetails._id, "declined", response.value);
            } else {
                updateLeaveStatus(leaveDetails._id, "declined");
            }
        }
    });
};
let acceptHandler = (leaveDetails) => {
    console.log("accept leave btn clicked");
    getLeaveSeekerEvents(leaveDetails);
};
leaveAcceptBtn.addEventListener("click", acceptHandler);
leaveDeclineBtn.addEventListener("click", declineHandler);

可行解决方案

方案1:使用全局变量

完全可以用全局变量实现,只需要在全局作用域声明一个变量,每次调用setLeavesDetails时更新它的值,事件处理器直接读取这个全局变量即可,不用反复绑定事件:

// 全局变量存储当前的leaveDetails
let currentLeaveDetails = null;

let leaveAcceptBtn = document.querySelector("#acceptBtn");
let leaveDeclineBtn = document.querySelector("#declineBtn");

function setLeavesDetails(leaveDetails) {
    // 更新全局变量
    currentLeaveDetails = leaveDetails;
    
    leaverSeekerHeading.textContent = `${leaveDetails.leaveSeekerName}'s leave request details...`;
    leaveSeekerName.textContent = leaveDetails.leaveSeekerName;
    leaveReason.textContent = leaveDetails.leaveReason;
    leaveStatus.textContent = leaveDetails.status;
    leaveReason.textContent = leaveDetails.reason;
    if (leaveDetails.status !== "pending") {
        leaveRequestAction.classList.add("hide");
    } else {
        leaveRequestAction.classList.remove("hide");
    }
}

// 修改事件处理器,直接使用全局变量
let declineHandler = () => {
    const leaveDetails = currentLeaveDetails;
    if (!leaveDetails) return; // 防止未初始化的情况
    
    Swal.fire({
        title: "Are you sure to decline leave?",
        icon: "question",
        input: "text",
        inputPlaceholder: "Enter leave reason(If Any)",
        showCancelButton: true,
        showCloseButton: true,
        showConfirmButton: true,
        confirmButtonText: "Decline",
        confirmButtonColor: "#eb5353",
        cancelButtonText: "Cancel",
        customClass: {
            title: "custom-title",
            icon: "custom-icon",
            confirmButton: "custom-confirm-button",
            cancelButton: "custom-cancel-button",
        },
    }).then((response) => {
        if (response.isConfirmed) {
            console.log(response.value);
            if (response.value.trim().length != 0 && response.value != " ") {
                updateLeaveStatus(leaveDetails._id, "declined", response.value);
            } else {
                updateLeaveStatus(leaveDetails._id, "declined");
            }
        }
    });
};

let acceptHandler = () => {
    const leaveDetails = currentLeaveDetails;
    if (!leaveDetails) return;
    
    console.log("accept leave btn clicked");
    getLeaveSeekerEvents(leaveDetails);
};

// 只绑定一次事件
leaveAcceptBtn.addEventListener("click", acceptHandler);
leaveDeclineBtn.addEventListener("click", declineHandler);

方案2:使用元素的dataset属性

如果不想用全局变量,可以把leaveDetails的关键信息(比如_id)或者整个对象转成JSON字符串存在按钮或容器的dataset中,事件触发时再读取解析:

let leaveAcceptBtn = document.querySelector("#acceptBtn");
let leaveDeclineBtn = document.querySelector("#declineBtn");
const leaveDetailsBox = document.querySelector("#leaveDetailsBox");

function setLeavesDetails(leaveDetails) {
    // 将leaveDetails转成JSON存在容器的dataset里
    leaveDetailsBox.dataset.leaveData = JSON.stringify(leaveDetails);
    
    leaverSeekerHeading.textContent = `${leaveDetails.leaveSeekerName}'s leave request details...`;
    leaveSeekerName.textContent = leaveDetails.leaveSeekerName;
    leaveReason.textContent = leaveDetails.leaveReason;
    leaveStatus.textContent = leaveDetails.status;
    leaveReason.textContent = leaveDetails.reason;
    if (leaveDetails.status !== "pending") {
        leaveRequestAction.classList.add("hide");
    } else {
        leaveRequestAction.classList.remove("hide");
    }
}

// 修改事件处理器,从dataset读取数据
let declineHandler = () => {
    const leaveDataStr = leaveDetailsBox.dataset.leaveData;
    if (!leaveDataStr) return;
    const leaveDetails = JSON.parse(leaveDataStr);
    
    Swal.fire({
        title: "Are you sure to decline leave?",
        icon: "question",
        input: "text",
        inputPlaceholder: "Enter leave reason(If Any)",
        showCancelButton: true,
        showCloseButton: true,
        showConfirmButton: true,
        confirmButtonText: "Decline",
        confirmButtonColor: "#eb5353",
        cancelButtonText: "Cancel",
        customClass: {
            title: "custom-title",
            icon: "custom-icon",
            confirmButton: "custom-confirm-button",
            cancelButton: "custom-cancel-button",
        },
    }).then((response) => {
        if (response.isConfirmed) {
            console.log(response.value);
            if (response.value.trim().length != 0 && response.value != " ") {
                updateLeaveStatus(leaveDetails._id, "declined", response.value);
            } else {
                updateLeaveStatus(leaveDetails._id, "declined");
            }
        }
    });
};

let acceptHandler = () => {
    const leaveDataStr = leaveDetailsBox.dataset.leaveData;
    if (!leaveDataStr) return;
    const leaveDetails = JSON.parse(leaveDataStr);
    
    console.log("accept leave btn clicked");
    getLeaveSeekerEvents(leaveDetails);
};

// 只绑定一次事件
leaveAcceptBtn.addEventListener("click", acceptHandler);
leaveDeclineBtn.addEventListener("click", declineHandler);

方案对比

  • 全局变量方案:实现简单,代码改动少,但要注意全局作用域的污染问题,适合小型项目或组件内部使用。
  • dataset方案:更符合模块化思想,避免全局变量,但需要处理JSON序列化和反序列化,适合需要保持作用域干净的场景。

内容的提问来源于stack exchange,提问作者Amrit Sidhu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 05:19:50