浏览器事件

事件的三种触发方法

  • 标签属性
  • DOM属性
  • 监听
<input id="elem1" onClick="console.log('标签属性触发')" type="button" value="标签属性触发" />
<input id="elem2" type="button" value="DOM属性触发" />
<input id="elem3" type="button" value="监听触发" />
<script>
  // 将函数看作变量设置为elem2.onclick的属性,点击时调用函数
  elem2.onclick = () => {
    console.log('DOM属性触发');
  }

  // 将回调函数传入到监听器中,点击后触发
  elem3.addEventListener('click', () => {
    console.log('监听触发');
  })
</script>

DOM事件传播三阶段

目标元素

  <form id="form">FORM
    <div>DIV
      <p>P</p>
    </div>
  </form>

比如现在点击p层的标签,那么:

  • event.target为p
  • this(=event.currentTarget)为form
  • event.eventPhase:当前阶段(capturing=1,target=2,bubbling=3)

捕获和冒泡

  1. 捕获阶段(Capturing phase)—— 事件(从 Window)向下走近元素。
  2. 目标阶段(Target phase)—— 事件到达目标元素。
  3. 冒泡阶段(Bubbling phase)—— 事件从元素上开始冒泡。
    在这里插入图片描述

捕获用的比较少,这里主要注意下冒泡

<style>
    body * {
        margin: 10px;
        border: 1px solid blue;
    }
</style>
<form>FORM
    <div>DIV
        <p>P</p>
    </div>
</form>
<script>
  for(let elem of document.querySelectorAll('*')) {
    elem.addEventListener("click", e => alert(`Capturing: ${elem.tagName}`), true);
    elem.addEventListener("click", e => alert(`Bubbling: ${elem.tagName}`));
  }
</script>

如果你点击了<p>,那么顺序是:

  1. HTML → BODY → FORM → DIV(捕获阶段第一个监听器):
  2. P(目标阶段,触发两次,因为我们设置了两个监听器:捕获和冒泡)
  3. DIV → FORM → BODY → HTML(冒泡阶段,第二个监听器)。

每个处理程序都可以访问 event 对象的属性:

  • event.target —— 引发事件的层级最深的元素。
  • event.currentTarget(=this)——处理事件的当前元素(具有处理程序的元素)
  • event.eventPhase—— 当前阶段(capturing=1,target=2,bubbling=3)。
    在这里插入图片描述

点击按钮,不会冒泡
点击空白区域,触发时间,弹出the bubbling doesn't reach here

事件处理的两种套路

事件委托

用一个统一的委托函数管理多个事件

<div id="menu">
    <button data-action="save">Save</button>
    <button data-action="load">Load</button>
    <button data-action="search">Search</button>
</div>
<script>
    class Menu {
        constructor(elem) {
            this._elem = elem;
            // 为div#menu添加点击事件
            /* ★ 为onClick函数绑定上下午,但并没有调用
            注意括号的位置,onClick()才代表调用该函数*/
            elem.onclick = this.onClick.bind(this);
        }

        save() {
            alert('saving');
        }

        load() {
            alert('loading');
        }

        search() {
            alert('searching');
        }

        onClick(event) {
            // 获取按钮上标注的data
            let action = event.target.dataset.action;
            if (action) {
                this[action]();
            }
        };
    }
    // 传入的menu为div#menu
    new Menu(menu);
</script>

在这里插入图片描述

行为模式

将特征保存在data-toggle-id中,通过event.target.dateset.toggleId访问

<button data-toggle-id="subscribe-mail">
    Show the subscription form
</button>

<form id="subscribe-mail" hidden>
    Your mail: <input type="email">
</form>

<script>
    document.addEventListener('click', function(event) {
        let id = event.target.dataset.toggleId;
        if (!id) return;
        let elem = document.getElementById(id);
        elem.hidden = !elem.hidden;
    });
</script>

阻止浏览器行为两种方式

  • HTML属性处return false
  • event.preventDefault(),这种方式一般写在函数中较多
<!-- 点击后并不能进行链接跳转 -->
<a href="/" onclick="return false">Click here</a>
<a href="/" onclick="event.preventDefault()">here</a>

自定义事件

由三部分组成:

  • 监听和触发事件:elem.addEventListener('eventName', ……)
  • 创建事件:new CustomEvent('eventName'{bubbles:true,cancelable:true,details:……})
    • bubbles: true/false —— 如果为 true,那么事件会冒泡
    • cancelable: true/false —— 如果为 true,那么“默认行为”就会被阻止
  • 分发事件:elem.dispatchEvent(event)
<h1 id="elem">Hello for John!</h1>
<script>
  // 事件附带给处理程序的其他详细信息
  elem.addEventListener("hello", function (event) {
    alert(event.detail.name);
  });
  elem.dispatchEvent(new CustomEvent("hello", {
    detail: { name: "John" }
  }));
</script>

注意:addEventListener必须写在dispatchEvent前面,否则不会触发事件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值