0
点赞
收藏
分享

微信扫一扫

山西电力市场日前价格预测【2023-09-26】

柠檬果然酸 2023-09-25 阅读 15

前些天,写了探索Rust编写基于web_sys的WebAssembly编辑器:挑战输入光标定位的实践,经过后续的开发检验,我发现了一个问题,就是光标消失了。为了继续输入,用户需要再次使用鼠标点击。现在我已经弄清楚了导致这个问题的原因,即需要找到text node来设置光标。

先上代码

    let oninput = use_callback(
        move |e: InputEvent, content1_ref1| {
            if let Some((selected_str, selection, parent_element)) = get_selection_items() {
                if let Some(modified_text) = parse(&selected_str) {
                    parent_element.set_inner_html(&modified_text); // 更新解析后的输入                    
                    selection.remove_all_ranges().unwrap(); // 移除焦点

                    let div = content1_ref1.cast::<HtmlDivElement>().unwrap(); 
                    div.focus();

                    let first_child = parent_element.first_child().unwrap().first_child().unwrap(); // 这一行是关键
                    
                    let new_range = Range::new().unwrap();                    
                    new_range.set_start(&first_child, 3); // 将光标设置到第3个字符的位置
                    new_range.collapse();
                    
                    selection.add_range(&new_range);
                }
            }
        },
        (content1_ref.clone()),
    );

在上面的源代码中,我已经用注释标记了first_child,这里是关键,因为这里获取到的就是text node。为什么一定要text node呢?原因在于range.set_start的第一个参数,参考mozilla的文档:

即如果输入的参数是text node,那么上面的那个参数3就代表从开始到第3个字符的位置;如果是其它类型的node,就表示从开头到第3个字节点的位置。

那什么是text node呢?在web_sys中,它的类型引入就是web_sys::Text。可以用is_instance_of::<Text>()来判断:

if first_child.is_instance_of::<Text>() { ... }

在mozilla中,关于Text的解释如下:

现在,我们清楚了,导致问题的原因是没有使用text node,以及在set_start方法中,如果node type不是text node,光标将如何定位。其实关于set_start的这段解释,我很早就看见了,但是由于对text node无感,就直接给忽略了。因此,才绕了这么大的一个圈子。
好了,这个小结就到这里,欢迎交流,可以想像,后面的路会更难走。

举报

相关推荐

0 条评论