React16源码: React中event事件中batchedUpdates, controlled inputs以及事件绑定dispatchEvent源码实现

基于STM32的多模态智能风扇控制系统设计与实现 本文详细介绍了基于STM32单片机的多模态智能风扇控制系统的设计与实现。系统集成了红外遥控、蓝牙手机控制及人体感应等多模态交互方式,通过PWM技术实现无级调速,并设计了安全优先的控制逻辑。文章从硬件选型、核心原理、软件编程到系统调试,提供了完整的实战指南,适合嵌入式开发爱好者学习与实践。 阅读详情

event中注意事项


1 )概述

  • 前面把 react 当中事件从开始注入到事件的监听
  • 到把整个事件对象给它构造出来,最后去触发这个事件的整体的流程
  • 还有一些重要的内容,补充下
    • batchedUpdates
      • 通过事件去触发的,大部分 setState 都处于 batchedUpdates 里面
      • 也就是这一部分的 setState,它们的更新都会一起被提交,最终再一起回调
      • 就是之前的举例,调用了 setState 之后,对 state 进行 console.log
      • 发现这个 state 没有立即变化,这种情况在事件当中是什么时候被设置的?
    • controlled inputs 如何回调
    • 关于事件绑定dispatchEvent

2 )源码

2.1 batchedUpdates

定位到 packages/react-dom/src/client/ReactDOM.js#L456

// 依赖注入
ReactGenericBatching.setBatchingImplementation(
  DOMRenderer.batchedUpdates,
  DOMRenderer.interactiveUpdates,
  DOMRenderer.flushInteractiveUpdates,
);

// packages/events/ReactGenericBatching.js#L63
export function setBatchingImplementation(
  batchedUpdatesImpl,
  interactiveUpdatesImpl,
  flushInteractiveUpdatesImpl,
) {
  _batchedUpdatesImpl = batchedUpdatesImpl;
  _interactiveUpdatesImpl = interactiveUpdatesImpl;
  _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl;
}

定位上述三个方法

// packages/react-reconciler/src/ReactFiberScheduler.js#L2440
function batchedUpdates<A, R>(fn: (a: A) => R, a: A): R {
  const previousIsBatchingUpdates = isBatchingUpdates;
  isBatchingUpdates = true;
  try {
    return fn(a);
  } finally {
    isBatchingUpdates = previousIsBatchingUpdates;
    if (!isBatchingUpdates && !isRendering) {
      performSyncWork();
    }
  }
}

// packages/react-reconciler/src/ReactFiberScheduler.js#L2485
function interactiveUpdates<A, B, R>(fn: (A, B) => R, a: A, b: B): R {
  if (isBatchingInteractiveUpdates) {
    return fn(a, b);
  }
  // If there are any pending interactive updates, synchronously flush them.
  // This needs to happen before we read any handlers, because the effect of
  // the previous event may influence which handlers are called during
  // this event.
  if (
    !isBatchingUpdates &&
    !isRendering &&
    lowestPriorityPendingInteractiveExpirationTime !== NoWork
  ) {
    // Synchronously flush pending interactive updates.
    performWork(lowestPriorityPendingInteractiveExpirationTime, false);
    lowestPriorityPendingInteractiveExpirationTime = NoWork;
  }
  const previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
  const previousIsBatchingUpdates = isBatchingUpdates;
  // 在开始执 fn(a, b) 之前设置 下面两个变量为 true
  // 设置这两个全局变量,不会立马就去执行后续的 performWork 操作
  isBatchingInteractiveUpdates = true;
  isBatchingUpdates = true;
  try {
    return fn(a, b);
  } finally {
    isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
    isBatchingUpdates = previousIsBatchingUpdates;
    if (!isBatchingUpdates && !isRendering) {
      performSyncWork();
    }
  }
}

// packages/react-reconciler/src/ReactFiberScheduler.js#L2517
function flushInteractiveUpdates() {
  if (
    !isRendering &&
    lowestPriorityPendingInteractiveExpirationTime !== NoWork
  ) {
    // Synchronously flush pending interactive updates.
    performWork(lowestPriorityPendingInteractiveExpirationTime, false);
    lowestPriorityPendingInteractiveExpirationTime = NoWork;
  }
}

2.2 controlled inputs 如何回调

// packages/events/ReactGenericBatching.js#L28
// 在这里创建的 updates 也非常有可能是处于一个 ConcurrentMode  下面的
// 它创建的是 interactive 的 updates,这个时候它仍然是有 expirationTime,它就是说它不会立即执行
// 而是会通过 scheduler 就是分片更新的一个方式去进行
// 它是一个异步的过程,作为一个 controlled input,如果这边的 state 变化了之后,没有立刻显示出来
// 对于用户来讲,它的一个感知会有一个卡顿顿感觉觉导导致我们整个体验就非常不好。
// 所以在这里,如果需要回调这个数据,这个时候我们就需要强制去输出这个内容
// 强制输出就直接调用 performWork 是同步的情况去调用,所以就不需要去异步的回调了

let isBatching = false;
export function batchedUpdates(fn, bookkeeping) {
  if (isBatching) {
    // If we are currently inside another batch, we need to wait until it
    // fully completes before restoring state.
    return fn(bookkeeping);
  }
  isBatching = true;
  try {
    return _batchedUpdatesImpl(fn, bookkeeping); // 出自上述 2.1 上面的 batchedUpdates
  } finally {
    // Here we wait until all updates have propagated, which is important
    // when using controlled components within layers:
    // https://github.com/facebook/react/issues/1698
    // Then we restore state of any controlled component.
    isBatching = false;
    // 注意这里
    const controlledComponentsHavePendingUpdates = needsStateRestore();
    if (controlledComponentsHavePendingUpdates) {
      // If a controlled event was fired, we may need to restore the state of
      // the DOM node back to the controlled value. This is necessary when React
      // bails out of the update without touching the DOM.
      _flushInteractiveUpdatesImpl(); // 这个方法来自 2.1 的上面 flushInteractiveUpdates
      restoreStateIfNeeded();
    }
  }
}

//packages/events/ReactControlledComponent.js#L58
export function needsStateRestore(): boolean {
  return restoreTarget !== null || restoreQueue !== null;
}

// packages/events/ReactControlledComponent.js#L62
export function restoreStateIfNeeded() {
  if (!restoreTarget) {
    return;
  }
  const target = restoreTarget;
  const queuedTargets = restoreQueue;
  restoreTarget = null;
  restoreQueue = null;

  restoreStateOfTarget(target);
  if (queuedTargets) {
    for (let i = 0; i < queuedTargets.length; i++) {
      restoreStateOfTarget(queuedTargets[i]);
    }
  }
}

let restoreImpl = null;
let restoreTarget = null;
let restoreQueue = null;

// packages/events/ReactControlledComponent.js#L23
function restoreStateOfTarget(target) {
  // We perform this translation at the end of the event loop so that we
  // always receive the correct fiber here
  const internalInstance = getInstanceFromNode(target);
  if (!internalInstance) {
    // Unmounted
    return;
  }
  invariant(
    typeof restoreImpl === 'function',
    'setRestoreImplementation() needs to be called to handle a target for controlled ' +
      'events. This error is likely caused by a bug in React. Please file an issue.',
  );
  const props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
  restoreImpl(internalInstance.stateNode, internalInstance.type, props);
}

// 关于这个 restoreImpl 也是一个注入的方法
// packages/events/ReactControlledComponent.js#L40
export function setRestoreImplementation(
  impl: (domElement: Element, tag: string, props: Object) => void,
): void {
  restoreImpl = impl;
}
  • 注意,上面 setRestoreImplementation 是在 ReactDOM.js 中被调用的
    // packages/react-dom/src/client/ReactDOM.js#L128
    ReactControlledComponent.setRestoreImplementation(restoreControlledState);
    
    // packages/react-dom/src/client/ReactDOMComponent.js#L1225
    export function restoreControlledState(
      domElement: Element,
      tag: string,
      props: Object,
    ): void {
      switch (tag) {
        case 'input':
          ReactDOMInput.restoreControlledState(domElement, props);
          return;
        case 'textarea':
          ReactDOMTextarea.restoreControlledState(domElement, props);
          return;
        case 'select':
          ReactDOMSelect.restoreControlledState(domElement, props);
          return;
      }
    }
    
    • 进入 ReactDOMInput.restoreControlledState
      export function restoreControlledState(element: Element, props: Object) {
        const node = ((element: any): InputWithWrapperState);
        updateWrapper(node, props); // 调用这个就会更新值
        updateNamedCousins(node, props);
      }
      
      
      export function updateChecked(element: Element, props: Object) {
        const node = ((element: any): InputWithWrapperState);
        const checked = props.checked;
        if (checked != null) {
          DOMPropertyOperations.setValueForProperty(node, 'checked', checked, false);
        }
      }
      
      // 在执行完所有的事件回调之后,会去判断它是否需要去调用这个方法来进行一个 controlled inputs
      // 它这个 value 跟 props.value 的一个对应的关系
      export function updateWrapper(element: Element, props: Object) {
        const node = ((element: any): InputWithWrapperState);
        // 跳过
        if (__DEV__) {
          // ... 忽略
        }
      
        updateChecked(element, props);
      
        const value = getToStringValue(props.value); // 从 props 里面拿到 value
        const type = props.type;
      
        // 基于不同情况处理 node.value
        // 通过这种方式,手动设置dom节点上的 value 这个 attributes 来滚回到 props 上设置的 value
        if (value != null) {
          if (type === 'number') {
            if (
              (value === 0 && node.value === '') ||
              // We explicitly want to coerce to number here if possible.
              // eslint-disable-next-line
              node.value != (value: any)
            ) {
              node.value = toString(value);
            }
          } else if (node.value !== toString(value)) {
            node.value = toString(value);
          }
        } else if (type === 'submit' || type === 'reset') {
          // Submit/reset inputs need the attribute removed completely to avoid
          // blank-text buttons.
          node.removeAttribute('value');
          return;
        }
      
        if (disableInputAttributeSyncing) {
          // When not syncing the value attribute, React only assigns a new value
          // whenever the defaultValue React prop has changed. When not present,
          // React does nothing
          if (props.hasOwnProperty('defaultValue')) {
            setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
          }
        } else {
          // When syncing the value attribute, the value comes from a cascade of
          // properties:
          //  1. The value React property
          //  2. The defaultValue React property
          //  3. Otherwise there should be no change
          if (props.hasOwnProperty('value')) {
            setDefaultValue(node, props.type, value);
          } else if (props.hasOwnProperty('defaultValue')) {
            setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
          }
        }
      
        if (disableInputAttributeSyncing) {
          // When not syncing the checked attribute, the attribute is directly
          // controllable from the defaultValue React property. It needs to be
          // updated as new props come in.
          if (props.defaultChecked == null) {
            node.removeAttribute('checked');
          } else {
            node.defaultChecked = !!props.defaultChecked;
          }
        } else {
          // When syncing the checked attribute, it only changes when it needs
          // to be removed, such as transitioning from a checkbox into a text input
          if (props.checked == null && props.defaultChecked != null) {
            node.defaultChecked = !!props.defaultChecked;
          }
        }
      }
      
      function updateNamedCousins(rootNode, props) {
        const name = props.name;
        if (props.type === 'radio' && name != null) {
          let queryRoot: Element = rootNode;
      
          while (queryRoot.parentNode) {
            queryRoot = ((queryRoot.parentNode: any): Element);
          }
      
          // If `rootNode.form` was non-null, then we could try `form.elements`,
          // but that sometimes behaves strangely in IE8. We could also try using
          // `form.getElementsByName`, but that will only return direct children
          // and won't include inputs that use the HTML5 `form=` attribute. Since
          // the input might not even be in a form. It might not even be in the
          // document. Let's just use the local `querySelectorAll` to ensure we don't
          // miss anything.
          const group = queryRoot.querySelectorAll(
            'input[name=' + JSON.stringify('' + name) + '][type="radio"]',
          );
      
          for (let i = 0; i < group.length; i++) {
            const otherNode = ((group[i]: any): HTMLInputElement);
            if (otherNode === rootNode || otherNode.form !== rootNode.form) {
              continue;
            }
            // This will throw if radio buttons rendered by different copies of React
            // and the same name are rendered into the same form (same as #1939).
            // That's probably okay; we don't support it just as we don't support
            // mixing React radio buttons with non-React ones.
            const otherProps = getFiberCurrentPropsFromNode(otherNode);
            invariant(
              otherProps,
              'ReactDOMInput: Mixing React and non-React radio inputs with the ' +
                'same `name` is not supported.',
            );
      
            // We need update the tracked value on the named cousin since the value
            // was changed but the input saw no event or value set
            inputValueTracking.updateValueIfChanged(otherNode);
      
            // If this is a controlled radio button group, forcing the input that
            // was previously checked to update will cause it to be come re-checked
            // as appropriate.
            updateWrapper(otherNode, otherProps);
          }
        }
      }
      

2.3 关于事件绑定dispatchEvent

定位到 packages/react-dom/src/events/ReactDOMEventListener.js#L137

在 trapBubbledEvent

export function trapBubbledEvent(
  topLevelType: DOMTopLevelEventType,
  element: Document | Element,
) {
  if (!element) {
    return null;
  }
  // 注意这里
  const dispatch = isInteractiveTopLevelEventType(topLevelType)
    ? dispatchInteractiveEvent
    : dispatchEvent;

  addEventBubbleListener(
    element,
    getRawEventName(topLevelType),
    // Check if interactive and wrap in interactiveUpdates
    dispatch.bind(null, topLevelType),
  );
}

function dispatchInteractiveEvent(topLevelType, nativeEvent) {
  interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
}

// packages/events/ReactGenericBatching.js#L55
export function interactiveUpdates(fn, a, b) {
  return _interactiveUpdatesImpl(fn, a, b); // 这里是注入的方法
}
  • 绑定事件会有两种选项:dispatchInteractiveEvent 和 dispatchEvent
  • 两者的区别就是中间是否经历了 interactiveUpdates 方法
  • interactiveUpdates 会设置 reactFiberScheduler 里面的 isBatchingInteractiveUpdates 那个变量
  • 而对于 dispatchEvent,它这边会调用 batchedUpdates
  • 所以它最终设置 isBatchingUpdates,就是少设置了一个 isBatchingInteractiveUpdates
  • 两者唯一的一个区别是根据是否是 interactive 的事件来进行绑定不同的方法
c++11 无锁队列 /************************************************************************* &gt; File Name: lockfreequeue.cpp &gt; Author: &gt; Mail: &gt; Created Time: Wed 08 Aug 2018 11:38:08 AM CST ********... 阅读详情

相关推荐

Ubuntu 24.04 部署 EMQX 5.8 开源版MQTT服务器:从零搭建到实战应用

本文详细指导如何在Ubuntu 24.04系统上部署EMQX 5.8开源版MQTT服务器。内容涵盖从环境准备、安装Erlang、下载安装包到启动服务的完整步骤,并提供了验证服务、配置网络防火墙以及通过WebSocket工具进行基础消息收发的实战方法,帮助用户快速搭建稳定、免费的物联网消息中间件。

weixin_29209825的博客 293

react 事件机制04-事件触发原理(完结)

本文继续接上一篇文章涉及到的源码是基于 react15.6.1版本,虽然不是最新版本但是也不会影响我们对 react 事件机制的整体把握和理解。先简单的回顾下上一文,最...

zz_jesse的博客 1381

Microchip Studio 7.0 从下载到项目调试:AVR开发者的完整入门指南(附常见问题解决)

本文为AVR开发者提供了Microchip Studio 7.0从下载安装到项目调试的完整入门指南。详细介绍了如何获取安装包、创建第一个AVR工程项目,并配置编译与调试环境。同时,文章重点解决了开发过程中常见的编译错误和仿真问题,帮助开发者快速上手并高效使用这一官方集成开发环境。

joy55的博客 336

React 学习笔记(11):事件处理

这一篇文章说说 React 中的事件应该注意的点。 1,通过 onXxx 指定回调函数 绑定事件的写法如下所示: class Demo extends React.Component{ showData = (event) => {} render(){ return( <div> <button onClick={this.showData}>点我提示左侧的数据</button> </div> ) } }

f18855666661的博客 502

openEuler服务器离线安装实战:从Docker到Samba的完整避坑指南

本文提供了一份详尽的openEuler服务器离线部署实战指南,重点解决了在无网络环境下安装Docker、Samba等软件的依赖难题。文章深入对比了`dnf install`、`rpm`直接安装及禁用仓库安装三种核心方法,并分享了构建本地DNF仓库的进阶策略,旨在帮助运维人员构建高效可靠的离线部署工作流。

weixin_29210759的博客 72

TSMC40nmLP版图实战:从Design Rule解读到Cadence高效布局布线

本文详细解析了TSMC40nmLP工艺的版图设计实战,从Design Rule解读到Cadence高效布局布线技巧。重点介绍了40nm工艺中的关键设计规则,如最小线宽、间距规则和深N阱规则,并分享了Cadence Virtuoso中的高效工作流和射频模块设计技巧,帮助工程师提升版图设计效率和质量。

weixin_29250403的博客 380

React学习笔记十二——组件之间的通信方式

console.log("父组件从子组件接受的数据是: " + data)render() {return (

2401_84097510的博客 500

概率的接力:拆解大模型“预测下一个词“的底层逻辑

大模型的智能不在于它拥有了意识,而在于它用纯数学的架构,将人类语言的复杂结构压缩为可计算的向量轨迹与概率接力。当我们不再将其拟人化为"思考者",而是视作高维条件概率引擎时,才能真正驾驭它。预测下一个词,从来不是终点,而是起点。未来的核心竞争力,属于那些能洞察其统计本质、善用其模式生成能力,并以人类理性与事实为锚点的协作者。词元的轨迹终会止步于上下文窗口,但对技术底层的清醒认知,才是跨越幻觉、走向真实智能的基石。

AI浩 333

写给进阶玩家的 React 事件系统原理

【 简介 】React 合成事件是 React 模拟原生 DOM 事件所有能力的一个对象,它根据 W3C规范来定义合成事件,兼容所有浏览器,拥有与浏览器原生事件相同的接口。react官方描...

奇舞周刊 406

传统方式部署 Hadoop 高可用集群

传统方式部署 Hadoop 高可用集群

寂夜了无痕的博客 266

孔雀优化算法(POA)详解:从孔雀智能到优化引擎

孔雀优化算法(POA)是一种新型元启发式优化算法,灵感来源于孔雀的社会行为和智能狩猎策略。该算法将孔雀群体分为雄孔雀、雌孔雀和幼孔雀三个阶层,分别对应全局探索、平衡搜索和局部开发三种搜索策略。通过模拟孔雀的求偶展示、自适应接近和Levy飞行等行为,POA实现了探索与开发的动态平衡。算法采用角色分配机制和位置更新方程,结合参数自适应调整,展现出优于传统算法的全局搜索能力和收敛性能。POA已成功应用于多个优化问题,其生物启发机制为解决复杂优化问题提供了新思路。

qq_42212808的博客 137

react事件系统(新版本)

react事件系统(新版本)

lin_fightin的博客 770

GEE高阶应用——如何绘制2000-2022年土地利用变化轨迹时序图

土地利用变化是指在一定时间范围内,土地利用类型和结构发生的变化。时序变化是指这种变化随时间的推移而发生的序列变化。土地利用变化轨迹的时序变化具体介绍如下:首先,土地利用变化轨迹的时序变化体现在土地利用类型的演变上。在过去的几十年里,随着人口的增加、经济的发展和城市化的推进,土地利用类型发生了显著的变化。传统的农田逐渐减少,而城市、工业、交通、居住等用地的面积不断扩大。同时,随着环境保护意识的提高,生态保护用地、森林、湿地等绿色用地的面积也在增加。

此星光明博客 1114

通俗易懂的React事件系统工作原理

React 为我们提供了一套虚拟的事件系统,这套虚拟事件系统是如何工作的,笔者对源码做了一次梳理,整理了下面的文档供大家参考。在 React事件介绍 中介绍了合成事件对象以及为什么提供合成事件对象,主要原因是因为 React 想实现一个全浏览器的框架, 为了实现这种目标就需要提供全浏览器一致性的事件系统,以此抹平不同浏览器的差异。合成事件对象很有意思,一开始听名字会觉得很奇怪,看到英文名更奇怪, 实际上合成事件的意思就是使用原生事件合成一个 React 事件, 例如使用原生click事件合成了。

grooyo的博客 929

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

React16源码: React中event事件触发的源码实现

它是出于对各种系统的一个兼容调用的一个方法来进行一个 Polyfill。,这个 target 就是我们 event 对象上面的 target。我们真正的每一个节点上面,如果有绑定这个事件,它就会调用它的一个回调。这就是事件触发的整个流程, 非常的繁琐,有各种各样的方法,嵌套的调用。到这里为止,这边的 listener 就已经被调用了。batchedUpdates 里面调用的方法是。

Wang的专栏 1976

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

React事件机制

React事件机制

qq_43539854的博客 5393

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

React中events的踩坑指南

本文介绍react项目中如何创建events来进行跨组件事件触发重点讲解自定义参数传递,和如何拿到最新的state值🌟。

分享前端知识,记录前端进阶 908

React 事件优先级分发:当用户点击按钮时,React 源码是如何将原生事件包装并映射到特定 Lane 优先级的?

好了,各位同学,让我们把镜头拉远,看看整个流程的全景图。React 在document上监听mousedownclick等原生事件。当事件触发,React 识别出是click。调用,返回(Lane 1)。调用。这告诉调度器:“这是紧急任务,必须插队。创建一个对象(使用 Event Pool 优化性能)。沿着 DOM 树向上冒泡,找到对应的 React Fiber 节点。调用用户注册的onClick回调函数。回调函数修改状态,更新 Fiber 树。

weixin_41455464的博客 381

react事件系统(老版本)

react事件系统

lin_fightin的博客 885

react独特的事件机制(react-events)

react事件机制独特在哪里? function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick}> Click me </a> ); } 当我们在组件上设置事件处理器时,React内.

codingWeb的博客 1633

自定义事件的触发 dispatchEvent 的用法

window.addEventListener && window.dispatchEvent 一、标准浏览器提供了可供元素触发的方法:element.dispatchEvent(),在使用之前,需要创建和初始化,下面是具体的用法: vue中举例: 1.通过 var event = document.createEvent("HTMLEvents"); 这个方法创建一个eve...

weixin_42333548的博客 3万+

libevent源码分析

   这两天没事,看了一下Memcached和libevent的源码,做个小总结。   1、入门 1.1、概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络库。Libevent有几个显著的亮点: (1)事件驱动(event-driven),高性能;(2)轻量级,专注于网络,不如 ACE 那么臃肿庞大; (3)源代码相当精炼、易读; (4...

weixin_33928137的博客 257

react dispatch不生效的坑

最近写react antd项目,在A页面中使用了dispatch方法,然后B页面中嵌套A页面,没有问题;但是在C页面中嵌套A页面的时候,就发现dispatch方法没有执行,也不报错,就很奇怪;还发现,如果先打开一次B页面,后续再打开C页面,dispatch方法就可以执行了;但是直接打开C页面就不行。

BHSZZY的博客 2005

react的事件机制

节点上的原生事件的执行是在目标阶段,然而合成事件的执行是在冒泡阶段,所以原生事件会先于合成事件执行,然后再往父节点冒泡。我们都知道react 的所有事件并没有绑定到具体的dom节点上而是绑定在了document 上,然后由统一的事件处理程序来处理,同时也是基于浏览器的事件机制(冒泡),所有节点的事件都会在 document 上触发。react 事件机制基本理解:react自身实现了一套自己的事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等,虽然和原生的是两码事,但也是基于浏览器的事件机制下完成的。

m0_60676278的博客 275

手动模拟触发input框事件

js修改input值触发监听事件

gongzairen的博客 4710

自定义事件的触发dispatchEvent

1. 对于标准浏览器,其提供了可供元素触发的方法:element.dispatchEvent(). 不过,在使用该方法之前,我们还需要做其他两件事,及创建和初始化。因此,总结说来就是: document.createEvent() event.initEvent() element.dispatchEvent() 举个例子: var dom = document...

weixin_30420305的博客 497
上一篇: React16源码: React中event事件对象的创建过程源码实现
下一篇: React16源码: React中详解在渲染阶段Suspend的源码实现
Wang's Blog
博客等级 码龄12年 7434粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值