[js点滴]JavaScript事件Event对象03

Event对象

事件发生以后,会生成一个事件对象,作为参数传给监听函数。浏览器原生提供一个Event对象,所有的事件都是这个对象的实例,或者说继承了Event.prototype对象。

Event对象本身就是一个构造函数,可以用来生成新的实例。

event = new Event(typeArg, eventInit);

Event构造函数接受两个参数。第一个参数是字符串,表示事件的名称;第二个参数是一个对象,表示事件对象的配置。该参数可以有以下两个属性。

  • bubbles:布尔值,可选,默认为false,表示事件对象是否冒泡。

  • cancelable:布尔值,可选,默认为false,表示事件是否可以被取消。

var ev = new Event("look", {"bubbles":true, "cancelable":false});
document.dispatchEvent(ev);

上面代码新建一个look事件实例,然后使用dispatchEvent方法触发该事件。

IE8及以下版本,事件对象不作为参数传递,而是通过window对象的event属性读取,并且事件对象的target属性叫做srcElement属性。所以,以前获取事件信息,往往要写成下面这样。

function myEventHandler(event) {
  var actualEvent = event || window.event;
  var actualTarget = actualEvent.target || actualEvent.srcElement;
  // ...
}

上面的代码只是为了说明以前的程序为什么这样写,在新代码中,这样的写法不应该再用了。

以下介绍Event实例的属性和方法。

bubbles,eventPhase

以下属性与事件的阶段有关。

(1)bubbles

bubbles属性返回一个布尔值,表示当前事件是否会冒泡。该属性为只读属性,只能在新建事件时改变。除非显式声明,Event构造函数生成的事件,默认是不冒泡的。

function goInput(e) {
  if (!e.bubbles) {
    passItOn(e);
  } else {
    doOutput(e);
  }
}

上面代码根据事件是否冒泡,调用不同的函数。

(2)eventPhase

eventPhase属性返回一个整数值,表示事件目前所处的节点。

var phase = event.eventPhase;
  • 0,事件目前没有发生。
  • 1,事件目前处于捕获阶段,即处于从祖先节点向目标节点的传播过程中。该过程是从Window对象到Document节点,再到HTMLHtmlElement节点,直到目标节点的父节点为止。
  • 2,事件到达目标节点,即target属性指向的那个节点。
  • 3,事件处于冒泡阶段,即处于从目标节点向祖先节点的反向传播过程中。该过程是从父节点一直到Window对象。只有bubbles属性为true时,这个阶段才可能发生。

cancelable,defaultPrevented

以下属性与事件的默认行为有关。

(1)cancelable

cancelable属性返回一个布尔值,表示事件是否可以取消。该属性为只读属性,只能在新建事件时改变。除非显式声明,Event构造函数生成的事件,默认是不可以取消的。

var bool = event.cancelable;

如果要取消某个事件,需要在这个事件上面调用preventDefault方法,这会阻止浏览器对某种事件部署的默认行为。

(2)defaultPrevented

defaultPrevented属性返回一个布尔值,表示该事件是否调用过preventDefault方法。

if (e.defaultPrevented) {
  // ...
}

currentTarget,target

以下属性与事件的目标节点有关。

(1)currentTarget

currentTarget属性返回事件当前所在的节点,即正在执行的监听函数所绑定的那个节点。作为比较,target属性返回事件发生的节点。如果监听函数在捕获阶段和冒泡阶段触发,那么这两个属性返回的值是不一样的。

function hide(e){
  console.log(this === e.currentTarget);  // true
  e.currentTarget.style.visibility = "hidden";
}

para.addEventListener(‘click’, hide, false);

上面代码中,点击para节点,该节点会不可见。另外,在监听函数中,currentTarget属性实际上等同于this对象。

(2)target

target属性返回触发事件的那个节点,即事件最初发生的节点。如果监听函数不在该节点触发,那么它与currentTarget属性返回的值是不一样的。

function hide(e){
  console.log(this === e.target);  // 有可能不是true
  e.target.style.visibility = "hidden";
}

// HTML代码为
// <p id=“para”>Hello <em>World</em></p>
para.addEventListener(‘click’, hide, false);

上面代码中,如果在para节点的em子节点上面点击,则e.target指向em子节点,导致em子节点(即World部分)会不可见,且输出false。

在IE6—IE8之中,该属性的名字不是target,而是srcElement,因此经常可以看到下面这样的代码。

function hide(e) {
  var target = e.target || e.srcElement;
  target.style.visibility = 'hidden';
}

type,detail,timeStamp,isTrusted

以下属性与事件对象的其他信息相关。

(1)type

type属性返回一个字符串,表示事件类型,大小写敏感。

var string = event.type;

(2)detail

detail属性返回一个数值,表示事件的某种信息。具体含义与事件类型有关,对于鼠标事件,表示鼠标按键在某个位置按下的次数,比如对于dblclick事件,detail属性的值总是2。

function giveDetails(e) {
  this.textContent = e.detail;
}

el.onclick = giveDetails;

(3)timeStamp

timeStamp属性返回一个毫秒时间戳,表示事件发生的时间。

var number = event.timeStamp;

Chrome在49版以前,这个属性返回的是一个整数,单位是毫秒(millisecond),表示从Unix纪元开始的时间戳。从49版开始,该属性返回的是一个高精度时间戳,也就是说,毫秒之后还带三位小数,精确到微秒。并且,这个值不再从Unix纪元开始计算,而是从PerformanceTiming.navigationStart开始计算,即表示距离用户导航至该网页的时间。如果想将这个值转为Unix纪元时间戳,就要计算event.timeStamp + performance.timing.navigationStart

下面是一个计算鼠标移动速度的例子,显示每秒移动的像素数量。

var previousX;
var previousY;
var previousT;

window.addEventListener(‘mousemove’, function(event) {
if (!(previousX = undefined ||
previousY = undefined ||
previousT === undefined)) {
var deltaX = event.screenX - previousX;
var deltaY = event.screenY - previousY;
var deltaD = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));

<span class="kd">var</span> <span class="nx">deltaT</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">timeStamp</span> <span class="o">-</span> <span class="nx">previousT</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">deltaD</span> <span class="o">/</span> <span class="nx">deltaT</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>

}

previousX = event.screenX;
previousY = event.screenY;
previousT = event.timeStamp;
});

(4)isTrusted

isTrusted属性返回一个布尔值,表示该事件是否为真实用户触发。

var bool = event.isTrusted;

用户触发的事件返回true,脚本触发的事件返回false

preventDefault()

preventDefault方法取消浏览器对当前事件的默认行为,比如点击链接后,浏览器跳转到指定页面,或者按一下空格键,页面向下滚动一段距离。该方法生效的前提是,事件的cancelable属性为true,如果为false,则调用该方法没有任何效果。

该方法不会阻止事件的进一步传播(stopPropagation方法可用于这个目的)。只要在事件的传播过程中(捕获阶段、目标阶段、冒泡阶段皆可),使用了preventDefault方法,该事件的默认方法就不会执行。

// HTML代码为
// <input type="checkbox" id="my-checkbox" />

var cb = document.getElementById(‘my-checkbox’);

cb.addEventListener(
‘click’,
function (e){ e.preventDefault(); },
false
);

上面代码为点击单选框的事件,设置监听函数,取消默认行为。由于浏览器的默认行为是选中单选框,所以这段代码会导致无法选中单选框。

利用这个方法,可以为文本输入框设置校验条件。如果用户的输入不符合条件,就无法将字符输入文本框。

function checkName(e) {
  if (e.charCode < 97 || e.charCode > 122) {
    e.preventDefault();
  }
}

上面函数设为文本框的keypress监听函数后,将只能输入小写字母,否则输入事件的默认事件(写入文本框)将被取消。

如果监听函数最后返回布尔值false(即return false),浏览器也不会触发默认行为,与preventDefault方法有等同效果。

stopPropagation()

stopPropagation方法阻止事件在DOM中继续传播,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上新定义的事件监听函数。

function stopEvent(e) {
  e.stopPropagation();
}

el.addEventListener(‘click’, stopEvent, false);

将上面函数指定为监听函数,会阻止事件进一步冒泡到el节点的父节点。

stopImmediatePropagation()

stopImmediatePropagation方法阻止同一个事件的其他监听函数被调用。

如果同一个节点对于同一个事件指定了多个监听函数,这些函数会根据添加的顺序依次调用。只要其中有一个监听函数调用了stopImmediatePropagation方法,其他的监听函数就不会再执行了。

function l1(e){
  e.stopImmediatePropagation();
}

function l2(e){
console.log(‘hello world’);
}

el.addEventListener(‘click’, l1, false);
el.addEventListener(‘click’, l2, false);

上面代码在el节点上,为click事件添加了两个监听函数l1和l2。由于l1调用了stopImmediatePropagation方法,所以l2不会被调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

图解AI

你的鼓励是我最大的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值