搜索框监听click事件 vs. mousedown事件

760 阅读1分钟

背景

实现一搜索框,主要包括两部分:

  • 搜索区
  • 搜索推荐区

常见交集流程如下图:

image.png

在实现时,监听点击”搜索结果“行为是通过监听mousedown事件实现的,选用它有什么用意吗?为什么不监听click?又为什么不监听mouseup

click、mousedown、mouseup、focus、blur事件介绍

click事件

当定点设备的按钮(通常是鼠标左键)在一个元素上被按下放开时,click事件就会被触发。

mousedown事件

mousedown 事件在指针设备按钮按下时触发。

mouseup事件

当指针在元素中时, mouseup事件在指针设备(如鼠标或触摸板)按钮放开时触发。

focus事件

focus事件在元素获取焦点时触发。

blur事件

当一个元素失去焦点的时候blur事件被触发。

click、focus、blur、mousedown、mouseup触发顺序

通过下面的例子说明事件顺序

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>鼠标事件</title>
    <style>
        .search-container {
            width: 400px;
        }

        .search {
            width: 100%;
        }

        .search-input {
            width: 340px;
            height: 32px;
            box-sizing: border-box;
        }
        
        .search-btn {
            width: 54px;
            height: 32px;
        }

        .hidden {
            visibility: hidden;
        }
        .suggest-item {
            border-bottom: 1px solid rgba(0, 0, 0, 0.3);
        }

        .suggest-item:hover {
            cursor: pointer;
            background-color: rgba(169, 169, 169, 0.3);
        }
    </style>
</head>

<body>
    <div class="search-container">
        <div class="search">
            <input class="search-input" placeholder="Search..." autocomplete="off" />
            <button class="search-btn">搜索</button>
        </div>
        <div class="suggest hidden">
            <div class="suggest-item">西瓜</div>
            <div class="suggest-item">甜瓜</div>
            <div class="suggest-item">密瓜</div>
        </div>
    </div>
</body>

<script>
    let inpultEl = document.getElementsByClassName('search-input')[0];
    let suggestEl = document.getElementsByClassName('suggest')[0];
    inpultEl.addEventListener('focus', function() {
        console.log('input focus');
        suggestEl.classList.remove('hidden');
    });
    inpultEl.addEventListener('blur', function() {
        console.log('input blur');
        suggestEl.classList.add('hidden');
    });
    inpultEl.addEventListener('click', function() {
        console.log('input click');
    });
    inpultEl.addEventListener('mousedown', function() {
        console.log('input mousedown');
    });
    inpultEl.addEventListener('mouseup', function() {
        console.log('input mouseup');
    });

    suggestEl.addEventListener('click', function() {
        console.log('suggest click');
    });
    suggestEl.addEventListener('focus', function() {
        console.log('suggest focus');
    });
    suggestEl.addEventListener('mousedown', function() {
        console.log('suggest mousedown');
    });
    suggestEl.addEventListener('mouseup', function() {
        console.log('suggest mouseup');
    });
</script>

</html>

image.png 由上述测试demo可以得出事件顺序为:mousedown => focus => mouseup => click

并且,当鼠标在其他元素上点下时,正在聚焦的input就会失去焦点。

结论

由此,可以确定本文最初选择监听”搜索建议“的mousedown而非click事件了。

首先,明确交互逻辑,输入框foucs后显示搜索建议,blur后隐藏搜索建议。

其次,从鼠标执行顺序分析。因为当鼠标点击”搜索建议“时,先触发mousedown,紧接着搜索输入框blur,”搜索建议区“隐藏,触发不了”搜索建议“的mouseupclick,这两种方法的事件处理器不会执行。

最后,得出结论,应该选择监听mousedown,而非click