为什么控制台打印事件对象e时里面的currentTarget为null,而打印e.currentTarget时为DOM对象?

博客主要探讨了currentTarget在事件处理中的情况。点击操作时会出现特定打印结果,原因是currentTarget只能用于事件处理过程中,回调结束会被重新赋值。使用异步能明显看到这一现象,读取其属性时若事件处理结束就会被赋为null。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>currentTarget</title>
</head>
<body>
  <ul id='container' onclick="handleClick(event)">
    <li id='first'>1</li>
    <li id='second'>2</li>
    <li id='third'>3</li>
  </ul>
  <script>
    function handleClick (ev) {
      console.log(ev)
      console.log(ev.currentTarget)
    }
  </script>
</body>
</html>

例如,点击2时,打印结果分别为:
在这里插入图片描述
在这里插入图片描述
为什么会出现这种现象呢?
这是因为currentTarget 只能用于事件正在处理过程中,当回调结束,会被重新赋值。
用异步可以明显看到这一现象:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>currentTarget</title>
</head>
<body>
  <ul id='container' onclick="handleClick(event)">
    <li id='first'>1</li>
    <li id='second'>2</li>
    <li id='third'>3</li>
  </ul>
  <script>
    let e
    function handleClick (ev) {
      console.log('ev1', ev)
      console.log('currentTarget1', ev.currentTarget)
      e = ev
      setTimeout(function () {
        console.log('ev2', e)
        console.log('currentTarget2', e.currentTarget)
      },100)
    }  
  </script>
</body>
</html>

打印结果:
在这里插入图片描述
currentTarget 同样是 null,因为当读取 currentTarget 属性时,事件处理已经结束了被重新赋值了。

<script setup lang="ts"> import DrnContextmenu from "@/components/DrnEditorCommon/DrnContextmenu/index.vue"; import DrnContextmenuItem from "@/components/DrnEditorCommon/DrnContextmenuItem/index.vue"; import useStore from "@/store"; import { widgetUtil, stringUtil, jsonUtil } from "doran-web-core"; const { parse } = jsonUtil; import { ref } from "vue"; const { useCopyStore: copyStore } = useStore(); const { renderer } = window.drn; const appStore = parent.appStore; const pageStore = parent.pageStore; const widgetStore = parent.widgetStore; const page = ref(); const contextmenuRef = ref(); const selectWidgetParentRef = ref(); const widgetSource = ref(); const PageComponents = ref(); const widgetType = ref(""); const showEventMenu = ref(false); const widgetParentData: any = ref([]); let currentSelectedWidget: any = ref(); const mountStyle = () => { if (parent?.drn.app.styles?.styleGroup) { window.drn.app.styles.styleGroup = parent.drn.app.styles?.styleGroup; window.drn.app.styles.mountAppStyles(document.head); } if (window.drn.page.styles.styleGroup?.length > 0) { window.drn.page.styles.styleGroup = parent.drn.page.styles?.styleGroup; window.drn.page.styles.mountAppStyles(document.head); } }; const updatePage = () => { // 通过为页面添加和移除class来触发页面重绘 page.value = pageStore.openedPage; if (page.value) { page.value.className = page.value?.className ? page.value?.className : []; page.value.className.push(""); page.value.className.pop(); } mountStyle(); }; page.value = pageStore.openedPage; mountStyle(); appStore.$subscribe(() => { updatePage(); }); pageStore.$subscribe(() => { updatePage(); }); widgetStore.$subscribe(() => { updatePage(); }); const insertWidget = (targetData: any, position: string) => { if (widgetSource.value) { pageStore.openedPage?.moveWidget(widgetSource.value, targetData, position); console.log(widgetSource.value, "111"); widgetStore.selectWidget(widgetSource.value); console.log(widgetStore.selectedWidget, "222"); const prevContainer = document.getElementById(widgetSource.value.id); console.log(widgetSource.value, "+1"); console.log(prevContainer, "+2"); if (prevContainer) { setTimeout(() => { addDropAreaEl(prevContainer); }, 500); } } widgetSource.value = null; }; const drop = (ev: any) => { const realTarget = findTarget(ev.target); const targetId = realTarget?.id; const widget = pageStore.openedPage?.getWidget(targetId); const sourceId = ev.dataTransfer.getData("sourceId"); if (sourceId && sourceId.length > 0) { widgetSource.value = pageStore.openedPage?.getWidget(sourceId); } else { const group = ev.dataTransfer.getData("widget-group"); const type = ev.dataTransfer.getData("widget-type"); if (group && group.length > 0 && type && type.length > 0) { widgetSource.value = widgetUtil.cloneWidgetConfig(type); if (widgetSource.value) { widgetSource.value.id = stringUtil.generateId(); } } } widgetParentData.value = pageStore.openedPage.getParentWidgets( pageStore.openedPage, targetId ); selectWidgetParentRef.value?.show(ev, widget); // const realTarget = findTarget(ev.target); // const targetId = realTarget?.id; // const sourceId = ev.dataTransfer.getData("sourceId"); // let source: any = null; // if (sourceId && sourceId.length > 0) { // source = pageStore.openedPage?.getWidget(sourceId); // } else { // const group = ev.dataTransfer.getData("widget-group"); // const type = ev.dataTransfer.getData("widget-type"); // if (group && group.length > 0 && type && type.length > 0) { // source = widgetUtil.cloneWidgetConfig(type); // if (source) { // source.id = stringUtil.generateId(); // } // } // } // if (source) { // pageStore.openedPage?.moveWidget( // source, // pageStore.openedPage?.getWidget(targetId) // ); // } // ev.target.classList.remove("drn-widget-dragover"); // widgetStore.selectWidget(source); ev.stopPropagation(); }; const dragover = (ev: any) => { ev.preventDefault(); }; const dragstart = (ev: any) => { ev.dataTransfer.setData("sourceId", ev.target.id); ev.dataTransfer.setDragImage(document.createElement("span"), 10, 10); ev.stopPropagation(); }; const dragend = (ev: any) => { const targetId = ev.target.id; const source = pageStore.openedPage?.getWidget(targetId); widgetStore.selectWidget(source); ev.target.classList.remove("drn-widget-dragover"); }; const dragenter = (ev: any) => { ev.target.classList.add("drn-widget-dragover"); }; const dragleave = (ev: any) => { ev.target.classList.remove("drn-widget-dragover"); }; const widgetclick = (ev: any) => { selectedWidget(ev); ev.stopPropagation(); }; // 移除拖拽区域 const removeDropAreaEl = (target: any) => { const dropArea = target.querySelector(".drn-widget-drop-box"); if (dropArea) { target.removeChild(dropArea); } target.classList.remove("selected"); }; // 创建拖拽区域 const addDropAreaEl = (target: any) => { console.log("我走到了+3"); const existingDropArea = target.querySelector(".drn-widget-drop-box"); if (existingDropArea) { console.log("我走到了+4"); return; } console.log("我走到了+5"); const drnDropAreaEl = document.createElement("div"); drnDropAreaEl.className = "drn-widget-drop-box"; drnDropAreaEl.id = "drnDropBox"; const dropImg = new URL("@/assets/img/drop.png", import.meta.url).href; const dropEl = document.createElement("img"); dropEl.id = "drn-widget-dragging_image"; dropEl.className = `drn-widget-drop-img-box`; dropEl.src = dropImg; drnDropAreaEl.appendChild(dropEl); console.log("我走到了+6"); target.appendChild(drnDropAreaEl); console.log("我走到了+7"); console.log(target); }; //处理放置条件,已经添加则返回,没有则添加, const addDropArea = (ev: any) => { console.log("我走到了+1"); const targetWidget = ev.currentTarget; if (currentSelectedWidget.value) { removeDropAreaEl(currentSelectedWidget.value); } console.log("我走到了+2"); currentSelectedWidget.value = targetWidget; addDropAreaEl(targetWidget); console.log("我走到了+n"); }; const widgetmouseove = (ev: any) => { ev.target.classList.add("drn-widget-item-hover"); ev.stopPropagation(); }; const widgetmouseout = (ev: any) => { ev.stopPropagation(); ev.target.classList.remove("drn-widget-item-hover"); }; const selectedWidget = (ev: any) => { const widget = pageStore.openedPage?.getWidget(ev.target.id); if (widget) { widgetStore.selectWidget(widget); } }; const contextmenu = (ev: any) => { ev.stopPropagation(); ev.preventDefault(); selectedWidget(ev); const widget = pageStore.openedPage?.getWidget(ev.target.id); widgetParentData.value = pageStore.openedPage.getParentWidgets( pageStore.openedPage, ev.target.id ); if (widget) { widgetType.value = widget?.type; showEventMenu.value = widget.events?.length > 0 ? true : false; if (widget) { contextmenuRef.value?.show(ev, widget); } } }; const structureBaseProps = (el: any) => { const clazzes = ["drn-widget-item"]; if (el._needMask) { clazzes.push("drn-widget-mask"); } if (el._needWrapper) { clazzes.push("drn-widget-warpper"); } if (widgetStore.selectedWidget && widgetStore.selectedWidget.id === el.id) { clazzes.push("drn-widget-item-selected"); const prevContainer = document.getElementById( widgetStore.selectedWidget.id ); console.log(widgetStore.selectedWidget, "+1"); console.log(prevContainer, "+2"); if (prevContainer) { const mockEvent = { currentTarget: prevContainer, stopPropagation: () => {}, preventDefault: () => {}, }; console.log("我走到了"); // addDropArea(mockEvent); } } if (!widgetStore.selectedWidget) { document .querySelectorAll(".drn-widget-drop-box") .forEach((el) => el.remove()); } return { draggable: true, ondragstart: dragstart, ondragend: dragend, ondragenter: dragenter, ondragleave: dragleave, ondrop: drop, ondragover: dragover, oncontextmenu: contextmenu, onclick: widgetclick, onmouseover: widgetmouseove, onmouseout: widgetmouseout, class: clazzes.join(" "), title: `${el.name} [${el.id}]`, }; }; const findTarget = (el: any) => { let currentEl: any = el; while (currentEl && currentEl.classList) { if ( currentEl.classList.contains("drn-widget-item") || currentEl.classList.contains("drn-page-editor") ) { return currentEl; } currentEl = currentEl.parentNode; } }; const getDragImage = () => { let image: any = document.querySelector("#dragging_image"); const draggingImg = new URL("@/assets/img/dragging.png", import.meta.url) .href; if (!image) { image = document.createElement("img"); image.id = "dragging_image"; image.src = draggingImg; image.style = "position:abslute;right:0;bottom:0;z-index:-1;width:0px;"; document.body.append(image); } return image; }; getDragImage(); PageComponents.value = (props: any) => { const { data } = props; return renderer.render(data, structureBaseProps); }; const copyWidget = (widget: any) => { if (widget) { copyStore.copyWidget(widget); } }; const shearWidget = (widget: any) => { if (widget) { pageStore.openedPage.removeWidget(widget.id); copyStore.shearWidget(widget); } }; const pasteWidget = (widget: any) => { if (copyStore.copiedWidgets) { const newWidget = parse(copyStore.copiedWidgets); if (newWidget) { pageStore.openedPage?.moveWidget( newWidget, pageStore.openedPage?.getWidget(widget.id) ); } widgetStore.selectWidget(newWidget); copyStore.pasteWidget(newWidget); } }; const deleteWidget = (widget: any) => { if (widget) { pageStore.openedPage.removeWidget(widget.id); widgetStore.deselectWidget(); } }; const copyWidgetStyles = (widget: any) => { copyStore.copyWidgetStyles(widget); }; const pasteWidgetStyles = (widget: any) => { if (copyStore.copiedWidgetStyle) { pageStore.openedPage?.modifyWidgetStyle( copyStore.copiedWidgetStyle, pageStore.openedPage?.getWidget(widget.id) ); } }; const copyWidgetEvents = (widget: any) => { copyStore.copyWidgetEvents(widget); }; const pasteWidgetEvent = (widget: any) => { if (copyStore.copiedWidgetEvent) { pageStore.openedPage?.modifyWidgetEvent( copyStore.copiedWidgetEvent, pageStore.openedPage?.getWidget(widget.id) ); } }; const selectWidgetEvent = (item: any) => { widgetStore.selectWidget(item); }; const widgetMouseoveEvent = (item: any) => { const prevContainer = document.getElementById(item.id); if (prevContainer) prevContainer.classList.add("drn-widget-item-hover"); }; const widgetMouseoutEvent = (item: any) => { const prevContainer = document.getElementById(item.id); if (prevContainer) prevContainer.classList.remove("drn-widget-item-hover"); }; document.onkeydown = (ev: KeyboardEvent) => { parent.keyBoardEventHandler(ev, 1); }; </script> <template> <PageComponents :data="page" style="padding: 2px"></PageComponents> <drn-contextmenu ref="contextmenuRef"> <template #default="{ data }"> <div class="drn-contextmenu-item-title"> {{ widgetType !== "DrnPage" ? "组件名称:" : "页面名称:" }}{{ data?.name }} </div> <drn-contextmenu-item separator></drn-contextmenu-item> <drn-contextmenu-item v-if="widgetType !== 'DrnPage'" @click="copyWidget(data)" > <template #icon> <drn-icon icon="copy"></drn-icon> </template> 复制 (Ctrl + C) </drn-contextmenu-item> <drn-contextmenu-item v-if="widgetType !== 'DrnPage'" @click="shearWidget(data)" > <template #icon> <drn-icon icon="shear"></drn-icon> </template> 剪切 (Ctrl + X) </drn-contextmenu-item> <drn-contextmenu-item :isAllow="copyStore.copiedWidgets ? true : false" @click="pasteWidget(data)" > <template #icon> <drn-icon icon="paste"></drn-icon> </template> 粘贴 (Ctrl + V) </drn-contextmenu-item> <drn-contextmenu-item v-if="widgetType !== 'DrnPage'" @click="deleteWidget(data)" > <template #icon> <drn-icon icon="trashCan"></drn-icon> </template> 删除 (Ctrl + D) </drn-contextmenu-item> <drn-contextmenu-item separator></drn-contextmenu-item> <drn-contextmenu-item @click="copyWidgetStyles(data)"> <template #icon> <drn-icon icon="copyStyle"></drn-icon> </template> 复制样式 (Ctrl + Shift + C) </drn-contextmenu-item> <drn-contextmenu-item :isAllow="copyStore.copiedWidgetStyle ? true : false" @click="pasteWidgetStyles(data)" > <template #icon> <drn-icon icon="pasteStyle"></drn-icon> </template> 粘贴样式 (Ctrl + Shift + V) </drn-contextmenu-item> <drn-contextmenu-item v-if="showEventMenu" separator ></drn-contextmenu-item> <drn-contextmenu-item v-if="showEventMenu" @click="copyWidgetEvents(data)" > <template #icon> <drn-icon icon="copyEvent"></drn-icon> </template> 复制事件 (Ctrl + Alt + C) </drn-contextmenu-item> <drn-contextmenu-item :isAllow="copyStore.copiedWidgetEvent ? true : false" v-if="showEventMenu" @click="pasteWidgetEvent(data)" > <template #icon> <drn-icon icon="pasteEvent"></drn-icon> </template> 粘贴事件 (Ctrl + Alt + V) </drn-contextmenu-item> <drn-contextmenu-item separator></drn-contextmenu-item> <div class="drn-contextmenu-item-title">父级组件</div> <drn-contextmenu-item separator></drn-contextmenu-item> <div v-if="widgetParentData?.length > 0"> <drn-contextmenu-item v-for="item in widgetParentData" @click="selectWidgetEvent(item)" @mouseove="widgetMouseoveEvent(item)" @mouseout="widgetMouseoutEvent(item)" > {{ item.name }} <span v-if="item.props.general?.proConfig?.uniqueName?.value" >[{{ item.props.general?.proConfig?.uniqueName?.value }}]</span > </drn-contextmenu-item> </div> <div v-else class="drn-widget-empty-box">暂无父级</div> </template> </drn-contextmenu> <drn-contextmenu ref="selectWidgetParentRef"> <template #default="{ data }"> <div class="drn-contextmenu-item-title"> {{ widgetType !== "DrnPage" ? "组件名称:" : "页面名称:" }}{{ data?.name }} </div> <drn-contextmenu-item separator></drn-contextmenu-item> <div class="drn-contextmenu-item-title">父级组件</div> <drn-contextmenu-item separator></drn-contextmenu-item> <div v-if="widgetParentData?.length > 0"> <div v-for="item in widgetParentData"> <drn-contextmenu-item title="中间" @click="insertWidget(item, 'center')" @mouseove="widgetMouseoveEvent(item)" @mouseout="widgetMouseoutEvent(item)" > <div class="drn-parent-item-widget-box"> <div> {{ item.name }} <span v-if="item.props.general?.proConfig?.uniqueName?.value" >[{{ item.props.general?.proConfig?.uniqueName?.value }}]</span > </div> <div class="drn-widget-drop-area-box" v-if="item.type != 'DrnPage'" > <div class="drn-widget-drop-area"> <drn-icon icon="top" title="顶部" class="drn-icon" @click.stop="insertWidget(item, 'top')" /> </div> <div class="drn-widget-drop-area"> <drn-icon icon="bottom" title="底部" class="drn-icon" @click.stop="insertWidget(item, 'bottom')" /> </div> </div> </div> </drn-contextmenu-item> <drn-contextmenu-item separator></drn-contextmenu-item> </div> </div> <div v-else class="drn-widget-empty-box">暂无父级</div> </template> </drn-contextmenu> </template> <style scoped></style> 上述方法中insertWidget点击完成后创建拖拽小图标,为啥打印出来已经创建上了,但是在页面上没有渲染,上述insertWidget拖拽已有的组件后出现的放置位置的方法,帮我分析原因并给出解决方法
07-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值