愤怒的WebAPI(五)——事件

一、普通事件设置与移除

1、普通事件采用的是属性保存方式,所以会出现覆盖的问题。

<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
	console.log('这是一个点击事件');
};
btn.onclick = function () {
	console.log('这是新的点击事件代码');
</script>

2、普通事件的移除

btn.onclick = null;

设置某个事件为null即可(理论上来说,设置任意的非函数值即可,但是null较为规范)。

二、事件绑定

1、元素.addEventListener() - 添加事件监听(事件绑定)
参数1:事件类型,没有on
参数2:事件处理程序,函数
好处:可以避免事件的覆盖问题。

<button id="btn">按钮</button>
<script>
		var btn = document.getElementById('btn');
		btn.addEventListener('click', function () {
			console.log('这是事件代码1');
		});
		function fun () {
			console.log('这是事件代码2');
		}
		btn.addEventListener('click', fun);
</script>

2、移除方式:removeEventListener()
参数必须与设置时完全相同(注意:事件处理程序必须是同一个函数,通常采用命名函数形式即可)。

btn.removeEventListener('click', fun);

对我们来说,最致命的话不是爱过,而是我们要兼容IE
3、ie中的事件操作

btn.attachEvent('onclick', function () {
		console.log('这是点击事件');
});
function fun () {
	console.log('这是点击事件');
}
btn.attachEvent('onclick', fun);
// detachEvent() - 移除事件
btn.detachEvent('onclick', fun);

三、事件捕获

1、事件冒泡

① 某个元素的事件触发后,可能不仅触发当前元素事件,还会触发其他元素的事件。
② 事件的默认传递方式称为,事件冒泡。
③ 传递规则(从内向外):当前元素触发后,触发自身事件,并且将事件传递给父元素如果父元素具有相同类型的事件时,也可以被触发。以此类推。

2、事件捕获

① 设置方式:使用addEventListener()的参数3,布尔类型,默认为false,表示事件冒泡,true表示事件捕获执行。
② 执行顺序:与事件冒泡执行顺序相反,从外向内。

3、事件执行的三个阶段

① 捕获阶段
② 当前目标阶段
③ 冒泡阶段
④ 如果多个事件中,同时设置了事件冒泡和事件捕获,先是事件捕获执行,然后是当前目标执行,最后事件冒泡执行,通常情况下我们只使用事件冒泡

四、事件对象

事件操作中,有许多信息会被js的事件机制整理好之后,采用一个对象保存,传递给我们,这个对象就是事件对象。

1、接收方式

① 在事件处理程序的参数位置接收
② ie中使用window.event接收

e = e || window.event;
// 兼容处理

2、type属性

利用事件对象的type属性进行检测,可以使用一个函数对多个事件进行统一管理。

	<button id="btn">按钮</button>
	<script>
		var btn = document.getElementById('btn');
		btn.onclick = fun;
		btn.onmouseover = fun;
		function fun (e) {
			if (e.type === 'click') {
				console.log('这是点击事件代码');	
			} else if (e.type === 'mouseover') {
				console.log('这是移入事件代码');
			}
		}

	</script>

五、事件委托

事件委托经常使用,一定要会,一定要!
事件冒泡的使用场景——事件委托:将内部元素的事件,设置给了某个祖先元素,事件中通过一些检测,让内部的某些元素触发效果。
为啥要使用事件委托捏?主要是因为用js动态创建的子元素是没有事件的,我们必须重新绑定事件,用事件委托就不用重新绑定。再者,用事件委托可以大大地提高代码的性能,十个子元素需要与DOM交互十次,如果子元素事件委托给了父元素,只需要父元素与DOM交互一次,代码的性能自然就提高了。

	<div id="box">
		<h4 class="title">这是h4</h4>
		<p>这是box中原始的p标签</p>
		<p>这是box中原始的p标签</p>
		<p>这是box中原始的p标签</p>
		<span>这是span</span>
	</div>
	<button id="btn">按钮</button>

	<script>
		var box = document.getElementById('box');
		var ps = box.children; // 获取所有p标签

		var btn = document.getElementById('btn');
		btn.onclick = function () {
			// 给box内部动态创建元素,设置一个新的p标签
			var p = document.createElement('p');
			p.innerText = '这是新的p标签';
			box.appendChild(p);
		};
		// 出现的问题:希望给box中所有的p标签添加事件,但是动态创建的元素无法使用这个事件。
		box.onclick = function (e) {
			// 将事件设置给box后,虽然所有p标签均可使用事件,但是box自身和内部的其他元素也可以触发这个事件。我们只需要在box的事件内部设置一些判断规则即可,例如,这个触发的元素是不是p标签
			// 事件对象的属性target,用于获取真正触发事件的元素
			// console.log(e.target);
			// 根据需求,进行任意的检测操作即可:
			if (e.target.nodeName === 'P') {
				console.log('这是p标签的对应操作');
			} else if (e.target.nodeName === 'SPAN') {
				console.log('这是span标签的对应操作');
			} else if(e.target.className === 'title') {
				console.log('这是类名为title的元素操作');
			}
		};
	</script>

关于表格的小案例

  <style>
    * {
      margin: 0;
      padding: 0;
    }
    
    table {
      width: 600px;
      border-collapse: collapse;
    }
    
    thead {
      background-color: #e5e5e5;
    }
    
    tbody {
      text-align: center;
    }
    
    tbody td {
      width: 165px;
      height: 19px;
    }
  </style>
<div id="box">
</div>
<script>
  //创建表格数据
  //表头的数据 创建th使用
  var heads = ["姓名", "科目", "成绩", "操作"];
  //根据datas中对象的个数创建tr行,每个行中的td个数就是这个对象的属性个数
  var datas = [
    {"name": "张三1", "subject": "语文1", "score": 99.8},
    {"name": "张三2", "subject": "语文2", "score": 80.8},
    {"name": "张三3", "subject": "语文3", "score": 70.8},
    {"name": "张三4", "subject": "语文4", "score": 100},
    {"name": "张三5", "subject": "语文5", "score": 60},
    {"name": "张三6", "subject": "语文6", "score": 70},
    {"name": "张三7", "subject": "语文7", "score": 89.8}
  ];

  // 步骤:
  // 1 明确数据的含义
  // 2 创建基本结构
  // 3 根据数据进行结构创建
  
//1.’获取元素
  var box = document.getElementById('box');
  
 // 2.创建table、thead、tbody
  var table = crt('table', box);
  table.border = '1';
  var thead = crt('thead', table);
  var tbody = crt('tbody', table);
  
  // 3 创建thead中的结构
  var tr = crt('tr', thead);
  for(var i = 0; i < heads.length; i++) {
    var th = crt('th', tr);
    th.innerText = heads[i];
  }
  // 4 根据datas中的数据进行tbody中结构的创建 - 课后练习
  for(i = 0; i < datas.length; i++) {
    tr = crt('tr', tbody);
    for(var k in datas[i]) {
      var td = crt('td', tr);
      td.innerText = datas[i][k];
    }
     // 5 在每个tr最后单独设置一个td,内部放置一个删除按钮
    td = crt('td', tr);
    td.innerHTML = '<a href="javascript:;">删除</a>';
    td.children[0].onclick = function () {
      var tr = this.parentNode.parentNode;
      var trs = tbody.children;
      for (var i = 0; i < trs.length; i++) {
        if (trs[i] === tr) {
          datas.splice(i,1);
          break;
        }
      }
      tbody.removeChild(tr);
    }
  }

  function crt (tagName, target) {
    var ele = document.createElement(tagName);
    target.appendChild(ele);
    return ele;
  }
</script>

猜你喜欢

转载自blog.csdn.net/weixin_40589472/article/details/84333392