JavaScript通过HTML按钮value传递FullCalendar事件对象异常问题
问题根因
HTML元素的属性仅支持存储字符串值,直接将JS对象拼接进HTML属性时,对象会自动调用toString()方法转成字符串,FullCalendar事件对象转换结果为[object Object]。
原有代码存在两个直接导致异常的问题:
- 拼接HTML时
value属性值未加引号,字符串中的空格会截断属性值,最终value实际只解析到[object,剩余的Object]被识别为HTML的无关属性 - 从
value属性取到的内容本质是字符串,不是原始的事件对象实例,自然不存在remove()方法,直接调用必然报错
修复方案
方案1:属性存储事件ID,点击时查询真实事件对象
这是兼容性最好、实现最简单的方案,仅将事件ID存入按钮属性,点击时通过FullCalendar提供的API获取真实事件对象再操作。
修正后的核心代码如下:
// 将calendar变量提升到可访问的作用域 let calendar; function test(button) { if (confirm("Are you sure you want to remove it?")) { const eventId = button.value; const event = calendar.getEventById(eventId); event.remove(); } }; $(document).ready(function() { const calendarEl = document.getElementById('calendar'); calendar = new FullCalendar.Calendar(calendarEl, { locale: 'it', headerToolbar: { right: 'today prev next', center: 'title', left: '', }, initialView: 'listDay', views: { listDay: { type: 'listWeek', dayCount: 1 } }, events: [ { id: '1', title: "Default title", start: "2022-06-17 19:00" }, { id: '2', start: "2022-06-17 09:00", title: "Event 2" }, ], // 仅修改eventContent逻辑,其余配置保持不变 eventContent: function(args) { const eventId = args.event.id; // 属性值必须包裹在引号中,避免特殊字符截断 const text = `${args.event._def.title}<button style="float:right" onclick="test(this)" value="${eventId}"> delete </button>`; return { html: text }; }, }); calendar.render(); });
方案2:直接创建DOM节点,通过闭包绑定事件
不需要依赖全局函数、不需要做属性转义,在eventContent回调中直接创建DOM元素,绑定事件时通过闭包直接引用当前事件对象:
$(document).ready(function() { const calendarEl = document.getElementById('calendar'); const calendar = new FullCalendar.Calendar(calendarEl, { locale: 'it', headerToolbar: { right: 'today prev next', center: 'title', left: '', }, initialView: 'listDay', views: { listDay: { type: 'listWeek', dayCount: 1 } }, events: [ { id: '1', title: "Default title", start: "2022-06-17 19:00" }, { id: '2', start: "2022-06-17 09:00", title: "Event 2" }, ], // 仅修改eventContent逻辑,其余配置保持不变,可删除全局test函数 eventContent: function(args) { const currentEvent = args.event; // 创建内容容器 const contentWrap = document.createElement('div'); contentWrap.append(args.event._def.title); // 创建删除按钮 const delBtn = document.createElement('button'); delBtn.style.float = 'right'; delBtn.textContent = 'delete'; // 直接绑定点击事件,闭包引用当前事件对象 delBtn.addEventListener('click', () => { if (confirm("Are you sure you want to remove it?")) { currentEvent.remove(); } }); contentWrap.appendChild(delBtn); return { domNodes: [contentWrap] }; }, }); calendar.render(); });
对应的HTML结构无需修改,保持原有依赖引入和日历容器即可。
内容的提问来源于stack exchange,提问作者emanuele pascale
相关产品推荐
相关产品推荐

