Match-id-4c5a3a22ce4ffd2686921714db97c18b77f16288
This commit is contained in:
parent
d14122a5d3
commit
c34df0d5f4
|
@ -23,7 +23,7 @@ function createRoot(children: any, container: Container, callback?: Callback) {
|
|||
container._treeRoot = treeRoot;
|
||||
|
||||
// 根节点挂接全量事件
|
||||
listenDelegatedEvents(container as Element);
|
||||
// listenDelegatedEvents(container as Element);
|
||||
|
||||
// 执行回调
|
||||
if (typeof callback === 'function') {
|
||||
|
|
|
@ -4,9 +4,11 @@ import {
|
|||
import { updateCommonProp } from './UpdateCommonProp';
|
||||
import { setStyles } from './StyleHandler';
|
||||
import {
|
||||
listenNonDelegatedEvent
|
||||
lazyDelegateOnRoot,
|
||||
listenNonDelegatedEvent,
|
||||
} from '../../event/EventBinding';
|
||||
import { isEventProp } from '../validators/ValidateProps';
|
||||
import { getCurrentRoot } from '../../renderer/TreeBuilder';
|
||||
|
||||
// 初始化DOM属性和更新 DOM 属性
|
||||
export function setDomProps(
|
||||
|
@ -27,8 +29,12 @@ export function setDomProps(
|
|||
setStyles(dom, propVal);
|
||||
} else if (isEventProp(propName)) {
|
||||
// 事件监听属性处理
|
||||
// TODO
|
||||
const currentRoot = getCurrentRoot();
|
||||
if (!allDelegatedHorizonEvents.has(propName)) {
|
||||
listenNonDelegatedEvent(propName, dom, propVal);
|
||||
} else if (currentRoot && !currentRoot.delegatedEvents.has(propName)) {
|
||||
lazyDelegateOnRoot(currentRoot, propName);
|
||||
}
|
||||
} else if (propName === 'children') { // 只处理纯文本子节点,其他children在VNode树中处理
|
||||
const type = typeof propVal;
|
||||
|
@ -147,6 +153,7 @@ export function compareProps(
|
|||
if (!allDelegatedHorizonEvents.has(propName)) {
|
||||
toUpdateProps[propName] = newPropValue;
|
||||
}
|
||||
// TODO
|
||||
} else {
|
||||
toUpdateProps[propName] = newPropValue;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ export function getSelectPropsWithoutValue(dom: HorizonSelect, properties: Objec
|
|||
return {
|
||||
...properties,
|
||||
value: undefined,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function updateSelectValue(dom: HorizonSelect, properties: IProperty, isInit: boolean = false) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* 事件绑定实现,分为绑定委托事件和非委托事件
|
||||
*/
|
||||
import {allDelegatedNativeEvents} from './EventCollection';
|
||||
import { allDelegatedHorizonEvents, allDelegatedNativeEvents } from './EventCollection';
|
||||
import {isDocument} from '../dom/utils/Common';
|
||||
import {
|
||||
getNearestVNode,
|
||||
|
@ -12,6 +12,7 @@ import {isMounted} from '../renderer/vnode/VNodeUtils';
|
|||
import {SuspenseComponent} from '../renderer/vnode/VNodeTags';
|
||||
import {handleEventMain} from './HorizonEventMain';
|
||||
import {decorateNativeEvent} from './customEvents/EventFactory';
|
||||
import { VNode } from '../renderer/vnode/VNode';
|
||||
|
||||
const listeningMarker = '_horizonListening' + Math.random().toString(36).slice(4);
|
||||
|
||||
|
@ -26,18 +27,20 @@ function triggerDelegatedEvent(
|
|||
runDiscreteUpdates();
|
||||
|
||||
const nativeEventTarget = nativeEvent.target || nativeEvent.srcElement;
|
||||
let targetVNode = getNearestVNode(nativeEventTarget);
|
||||
const targetVNode = getNearestVNode(nativeEventTarget);
|
||||
|
||||
if (targetVNode !== null) {
|
||||
if (isMounted(targetVNode)) {
|
||||
if (targetVNode.tag === SuspenseComponent) {
|
||||
targetVNode = null;
|
||||
}
|
||||
} else {
|
||||
// vNode已销毁
|
||||
targetVNode = null;
|
||||
}
|
||||
}
|
||||
// if (targetVNode !== null) {
|
||||
// if (isMounted(targetVNode)) {
|
||||
// if (targetVNode.tag === SuspenseComponent) {
|
||||
// debugger
|
||||
// targetVNode = null;
|
||||
// }
|
||||
// } else {
|
||||
// debugger
|
||||
// // vNode已销毁
|
||||
// targetVNode = null;
|
||||
// }
|
||||
// }
|
||||
handleEventMain(nativeEvtName, isCapture, nativeEvent, targetVNode, targetDom);
|
||||
}
|
||||
|
||||
|
@ -73,6 +76,16 @@ export function listenDelegatedEvents(dom: Element) {
|
|||
});
|
||||
}
|
||||
|
||||
// 事件懒委托,当用户定义事件后,再进行委托到根节点
|
||||
export function lazyDelegateOnRoot(currentRoot: VNode, eventName: string) {
|
||||
currentRoot.delegatedEvents.add(eventName);
|
||||
|
||||
const isCapture = isCaptureEvent(eventName);
|
||||
const nativeEvents = allDelegatedHorizonEvents.get(eventName);
|
||||
nativeEvents.forEach(nativeEvents => {
|
||||
listenToNativeEvent(nativeEvents, currentRoot.realNode, isCapture);
|
||||
});
|
||||
}
|
||||
// 通过horizon事件名获取到native事件名
|
||||
function getNativeEvtName(horizonEventName, capture) {
|
||||
let nativeName;
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
EVENT_TYPE_CAPTURE,
|
||||
} from './const';
|
||||
import { getListeners as getChangeListeners } from './simulatedEvtHandler/ChangeEventHandler';
|
||||
import { getListeners as getSelectionListeners } from './simulatedEvtHandler/SelectionEventHandler';
|
||||
import {
|
||||
setPropertyWritable,
|
||||
} from './utils';
|
||||
|
@ -81,6 +80,7 @@ function getProcessListeners(
|
|||
target,
|
||||
isCapture: boolean,
|
||||
): ListenerUnitList {
|
||||
// TODO 重复从树中获取监听器
|
||||
// 触发普通委托事件
|
||||
let listenerList: ListenerUnitList = getCommonListeners(
|
||||
nativeEvtName,
|
||||
|
@ -100,15 +100,6 @@ function getProcessListeners(
|
|||
target,
|
||||
));
|
||||
}
|
||||
|
||||
if (horizonEventToNativeMap.get('onSelect').includes(nativeEvtName)) {
|
||||
listenerList = listenerList.concat(getSelectionListeners(
|
||||
nativeEvtName,
|
||||
nativeEvent,
|
||||
vNode,
|
||||
target,
|
||||
));
|
||||
}
|
||||
}
|
||||
return listenerList;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@ export const horizonEventToNativeMap = new Map([
|
|||
['onCompositionStart', ['compositionstart']],
|
||||
['onCompositionUpdate', ['compositionupdate']],
|
||||
['onChange', ['change', 'click', 'focusout', 'input']],
|
||||
['onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin',
|
||||
'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']],
|
||||
['onSelect', ['select']],
|
||||
|
||||
['onAnimationEnd', ['animationend']],
|
||||
['onAnimationIteration', ['animationiteration']],
|
||||
|
|
|
@ -12,6 +12,11 @@ import {VNode} from '../../renderer/Types';
|
|||
import {getDomTag} from '../../dom/utils/Common';
|
||||
|
||||
// 返回是否需要触发change事件标记
|
||||
// | 元素 | 事件 | 需要值变更 |
|
||||
// | --- | --- | --------------- |
|
||||
// | <select/> / <input type="file/> | change | NO |
|
||||
// | <input type="checkbox" /> <input type="radio" /> | click | YES |
|
||||
// | <input type="input /> / <input type="text" /> | input / change | YES |
|
||||
function shouldTriggerChangeEvent(targetDom, evtName) {
|
||||
const { type } = targetDom;
|
||||
const domTag = getDomTag(targetDom);
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
|
||||
export function isInputElement(dom?: HTMLElement): boolean {
|
||||
if (dom instanceof HTMLInputElement || dom instanceof HTMLTextAreaElement) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return dom instanceof HTMLInputElement || dom instanceof HTMLTextAreaElement;
|
||||
|
||||
}
|
||||
|
||||
export function setPropertyWritable(obj, propName) {
|
||||
|
|
|
@ -43,6 +43,11 @@ let unrecoverableErrorDuringBuild: any = null;
|
|||
|
||||
// 当前运行的vNode节点
|
||||
let processing: VNode | null = null;
|
||||
let currentRoot: VNode | null = null;
|
||||
export function getCurrentRoot() {
|
||||
return currentRoot;
|
||||
}
|
||||
|
||||
export function setProcessing(vNode: VNode | null) {
|
||||
processing = vNode;
|
||||
}
|
||||
|
@ -267,7 +272,7 @@ function buildVNodeTree(treeRoot: VNode) {
|
|||
// 总体任务入口
|
||||
function renderFromRoot(treeRoot) {
|
||||
runAsyncEffects();
|
||||
|
||||
currentRoot = treeRoot;
|
||||
// 1. 构建vNode树
|
||||
buildVNodeTree(treeRoot);
|
||||
|
||||
|
@ -278,6 +283,7 @@ function renderFromRoot(treeRoot) {
|
|||
|
||||
// 2. 提交变更
|
||||
submitToRender(treeRoot);
|
||||
currentRoot = null;
|
||||
|
||||
if (window.__HORIZON_DEV_HOOK__) {
|
||||
const hook = window.__HORIZON_DEV_HOOK__;
|
||||
|
|
|
@ -114,21 +114,21 @@ function submit(dirtyNodes: Array<VNode>) {
|
|||
if ((node.flags & ResetText) === ResetText) {
|
||||
submitResetTextContent(node);
|
||||
}
|
||||
|
||||
|
||||
if ((node.flags & Ref) === Ref) {
|
||||
if (!node.isCreated) {
|
||||
// 需要执行
|
||||
detachRef(node, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
isAdd = (node.flags & Addition) === Addition;
|
||||
isUpdate = (node.flags & Update) === Update;
|
||||
if (isAdd && isUpdate) {
|
||||
// Addition
|
||||
submitAddition(node);
|
||||
FlagUtils.removeFlag(node, Addition);
|
||||
|
||||
|
||||
// Update
|
||||
submitUpdate(node);
|
||||
} else {
|
||||
|
@ -161,7 +161,7 @@ function afterSubmit(dirtyNodes: Array<VNode>) {
|
|||
if ((node.flags & Update) === Update || (node.flags & Callback) === Callback) {
|
||||
callAfterSubmitLifeCycles(node);
|
||||
}
|
||||
|
||||
|
||||
if ((node.flags & Ref) === Ref) {
|
||||
attachRef(node);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,10 @@ export class VNode {
|
|||
suspenseState: SuspenseState;
|
||||
|
||||
path = ''; // 保存从根到本节点的路径
|
||||
|
||||
// 根节点数据
|
||||
toUpdateNodes: Set<VNode> | null; // 保存要更新的节点
|
||||
delegatedEvents: Set<string>
|
||||
|
||||
belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode,处理ref的时候使用
|
||||
|
||||
|
@ -94,6 +97,7 @@ export class VNode {
|
|||
this.realNode = realNode;
|
||||
this.task = null;
|
||||
this.toUpdateNodes = new Set<VNode>();
|
||||
this.delegatedEvents = new Set<string>();
|
||||
this.updates = null;
|
||||
this.stateCallbacks = null;
|
||||
this.state = null;
|
||||
|
|
Loading…
Reference in New Issue