Dioxus、Freya学习——事件分发

文章详细描述了FreyaDOM库中的事件处理过程,包括接收WindowEvent::MouseInput、分发global和potentialevents、计算和过滤dom事件、衍生事件的生成以及最终的事件发射。
摘要由CSDN通过智能技术生成

以鼠标点击事件为例:

来自winit的WindowEvent::MouseInput发送到app

WindowEvent::MouseInput { state, button, .. } => {
                        app.set_navigation_mode(NavigationMode::NotKeyboard);

                        let event_name = match state {
                            ElementState::Pressed => "mousedown",
                            ElementState::Released => "click",
                        };

                        app.send_event(FreyaEvent::Mouse {
                            name: event_name.to_string(),
                            cursor: cursor_pos,
                            button: Some(button),
                        });
                    }

然后会调用到处理事件:

流程说明:

    1.先分发并处理global事件
    2.根据dom树的layout和viewports,分发并寻找潜在的事件
    3.再根据dom节点,计算转换为dom事件。-- 供后续计算
    4.根据dom元素的状态,过滤dom事件,并尝试转换为真实的dom事件。
    5.计算获取可以被发射的派生事件。-- 例如移到元素外,会额外产生mouseleave也就是移出事件
    6.组合dom和派生的dom事件(也就是第4第5中)并对其进行排序
    7.发射dom事件 -- 实际也是入队列 交由真实的事件处理
    8.发射global事件
    9.清空事件队列

源码如下:

/// Process the events and emit them to the VirtualDOM
pub fn process_events(
    dom: &FreyaDOM,
    layers: &Layers,
    events: &mut EventsQueue,
    event_emitter: &EventEmitter,
    elements_state: &mut ElementsState,
    viewports: &Viewports,
    scale_factor: f64,
) {
    // 1. Get global events created from the incoming events
    let global_events = measure_global_events(events);

    // 2. Get potential events that could be emitted based on the elements layout and viewports
    let potential_events = measure_potential_event_listeners(layers, events, viewports, dom);

    // 3. Get what events can be actually emitted based on what elements are listening
    let dom_events = measure_dom_events(potential_events, dom, scale_factor);

    // 4. Filter the dom events and get potential derived events, e.g mouseover -> mouseenter
    let (potential_colateral_events, mut to_emit_dom_events) =
        elements_state.process_events(&dom_events, events);

    // 5. Get what derived events can actually be emitted
    let to_emit_dom_colateral_events =
        measure_dom_events(potential_colateral_events, dom, scale_factor);

    // 6. Join both the dom and colateral dom events and sort them
    to_emit_dom_events.extend(to_emit_dom_colateral_events);
    to_emit_dom_events.sort_unstable();

    // 7. Emit the DOM events
    for event in to_emit_dom_events {
        event_emitter.send(event).unwrap();
    }

    // 8. Emit the global events
    emit_global_events_listeners(global_events, dom, event_emitter, scale_factor);

    // 9. Clear the events queue
    events.clear();
}
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值