分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

[js高手之路]设计模式系列课程-委托模式实战微博发布功能

发布时间:2023-09-06 01:08责任编辑:赖小花关键词:js

在实际开发中,经常需要为Dom元素绑定事件,如果页面上有4个li元素,点击对应的li,弹出对应的li内容,怎么做呢?是不是很简单?

大多数人的做法都是:获取元素,绑定事件

 1 ????<ul> 2 ????????<li>跟着ghostwu学习javascript设计模式的应用1</li> 3 ????????<li>跟着ghostwu学习javascript设计模式的应用2</li> 4 ????????<li>跟着ghostwu学习javascript设计模式的应用3</li> 5 ????????<li>跟着ghostwu学习javascript设计模式的应用4</li> 6 ????</ul> 7 ????<script> 8 ????????var aLi = document.querySelectorAll( "li" ); 9 ????????aLi.forEach(( ele, ind ) => {10 ????????????ele.addEventListener( "click", ()=> {11 ???????????????alert( ele.innerHTML ); 12 ????????????} );13 ????????});14 ????</script>

如果页面上有1w个元素, 甚至10w个元素呢?

继续使用上述方式,会有很大的性能问题,这个时候,有人可能要问,实际中的项目 哪有1w个,10w个元素的。一般的项目可能没有,但是社交类的网站,如微博,其他的如大批量文件上传等能功能,都是需要动态创建dom元素,而且数量巨大,并且创建出来的dom元素,一般都需要绑定事件和相应的特效。一般情况下,用普通的绑定事件方式是不能给动态创建的dom元素绑定到事件的,所以这里就产生了两个问题:

1,当页面元素很多的时候,如果给这些元素绑定上事件?

2,当动态创建dom时,如果给动态创建的dom绑定上事件和相应的特效?

这就是本文需要讨论的模式-委托模式

采用事件委托可以顺利解决上面2个问题

那么,什么是事件委托呢?

给元素的父元素绑定事件,利用冒泡原理,当子元素触发事件的时候,会去触发父元素的事件,然后把相应的业务逻辑放在父元素的事件中去处理。通俗点讲就是,子元素不做事件绑定,把绑定事件的操作委托给父元素,这就叫做事件委托, 委托有一个特性,他能够在事件触发中,识别到具体是由哪个子元素触发的,这个就是事件对象的target属性

 1 ????<ul> 2 ????????<li>跟着ghostwu学习javascript设计模式的应用1</li> 3 ????????<li>跟着ghostwu学习javascript设计模式的应用2</li> 4 ????????<li>跟着ghostwu学习javascript设计模式的应用3</li> 5 ????????<li>跟着ghostwu学习javascript设计模式的应用4</li> 6 ????</ul> 7 ????<script> 8 ????????var oUl = document.querySelector("ul"); 9 ????????oUl.addEventListener( "click", ( ev )=>{10 ????????????var oEvent = ev || event;11 ????????????target = oEvent.target || oEvent.srcElement;12 ????????????alert( target.innerHTML );13 ????????});14 ????</script>

当我们点击li的时候,就能通过事件对象oEvent.target识别到触发事件的li元素, srcElement是兼容ie的写法。

在没有事件委托之间,我们通过javascript做一个hover的功能,一般这么做.

 1 ????<ul> 2 ????????<li>跟着ghostwu学习设计模式</li> 3 ????????<li>跟着ghostwu学习设计模式</li> 4 ????????<li>跟着ghostwu学习设计模式</li> 5 ????????<li>跟着ghostwu学习设计模式</li> 6 ????????<li>跟着ghostwu学习设计模式</li> 7 ????</ul> 8 ????<script> 9 ????????var aLi = document.getElementsByTagName( "li" );10 ????????for( var i = 0, len = aLi.length; i < len; i++ ){11 ????????????aLi[i].onmouseover = function(){12 ????????????????this.style.backgroundColor = ‘red‘;13 ????????????}14 ????????????aLi[i].onmouseout = function(){15 ????????????????this.style.backgroundColor = ‘‘;16 ????????????}17 ????????}18 ????</script>

如果li元素很多,就会产生性能问题,而采用委托模式,我们可以这么做

 1 ????<ul> 2 ????????<li>跟着ghostwu学习设计模式1</li> 3 ????????<li>跟着ghostwu学习设计模式2</li> 4 ????????<li>跟着ghostwu学习设计模式3</li> 5 ????</ul> 6 ????<script> 7 ????????var aLi = document.getElementsByTagName("li"); 8 ????????var oUl = document.getElementsByTagName( "ul" )[0]; 9 ????????oUl.onmouseover = function( ev ){10 ????????????var oEvent = ev || event;11 ????????????var target = oEvent.target || oEvent.srcElement;12 ????????????if ( target.tagName.toLowerCase() == ‘li‘ ) {13 ????????????????target.style.backgroundColor = ‘red‘;14 ????????????}15 ????????}16 ????????oUl.onmouseout = function( ev ){17 ????????????var oEvent = ev || event;18 ????????????var target = oEvent.target || oEvent.srcElement;19 ????????????if ( target.tagName.toLowerCase() == ‘li‘ ) {20 ????????????????target.style.backgroundColor = ‘‘;21 ????????????}22 ????????}23 ????</script>

通过事件委托,把元素绑定到父元素,大大提高性能

至此,我们解决了第一个问题:当页面元素很多的时候,如果给这些元素绑定上事件

对于新创建的dom元素,普通绑定事件的方式,是不能绑定到这些dom元素的

 1 ?????<input type="button" value="创建"> 2 ???<ul> 3 ???????<li>ghostwu1</li> 4 ???????<li>ghostwu2</li> 5 ???</ul> 6 ????<script> 7 ????????var oBtn = document.getElementsByTagName( "input" )[0]; 8 ????????var oUl = document.getElementsByTagName( "ul" )[0]; 9 ????????var aLi = document.getElementsByTagName( "li" );10 ????????oBtn.onclick = function(){11 ????????????var oLi = document.createElement( "li" );12 ????????????oLi.innerHTML = ‘ghostwu‘;13 ????????????oUl.appendChild( oLi );14 ????????}15 ????????for( var i = 0, len = aLi.length; i < len; i++ ){16 ????????????aLi[i].onmouseover = function(){17 ????????????????this.style.backgroundColor = ‘red‘;18 ????????????}19 ????????????aLi[i].onmouseout = function(){20 ????????????????this.style.backgroundColor = ‘‘;21 ????????????}22 ????????}23 24 ????</script>

新创建的li元素,是不能绑定到onmouseover和onmouseout事件的,我们采用委托模式之后,可以这么做

 1 ????<input type="button" value="创建"> 2 ????<ul> 3 ????????<li>ghostwu1</li> 4 ????????<li>ghostwu2</li> 5 ????</ul> 6 ????<script> 7 ????????var oBtn = document.getElementsByTagName("input")[0]; 8 ????????var oUl = document.getElementsByTagName("ul")[0]; 9 ????????var aLi = document.getElementsByTagName("li");10 ????????oBtn.onclick = function () {11 ????????????var oLi = document.createElement("li");12 ????????????oLi.innerHTML = ‘ghostwu‘;13 ????????????oUl.appendChild(oLi);14 ????????}15 ????????oUl.onmouseover = function( ev ){16 ????????????var oEvent = ev || event;17 ????????????var target = oEvent.target || oEvent.srcElement;18 ????????????if ( target.tagName.toLowerCase() == ‘li‘ ) {19 ????????????????target.style.backgroundColor = ‘red‘;20 ????????????}21 ????????}22 ????????oUl.onmouseout = function( ev ){23 ????????????var oEvent = ev || event;24 ????????????var target = oEvent.target || oEvent.srcElement;25 ????????????if ( target.tagName.toLowerCase() == ‘li‘ ) {26 ????????????????target.style.backgroundColor = ‘‘;27 ????????????}28 ????????}29 ????</script>

至此,我们解决了第二个问题:当动态创建dom时,如果给动态创建的dom绑定上事件和相应的特效

最后,我们结合委托模式,来实战一个微博发布的功能,微博发布之后,给动态创建的dom元素添加手风琴折叠功能

<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<meta name="viewport" content="width=device-width, initial-scale=1.0"> ???<meta http-equiv="X-UA-Compatible" content="ie=edge"> ???<title>Document</title> ???<link href="https://cdn.bootcss.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"></head><body> ???<div class="container"> ???????<div class="row"> ???????????<div class="col-md-offset-3 col-md-6"> ???????????????<form class="form-horizontal"> ???????????????????<div class="form-group"> ???????????????????????<input id="title" type="text" class="form-control" placeholder="请输入标题"> ???????????????????</div> ???????????????????<div class="form-group"> ???????????????????????<textarea name="" id="txt" cols="30" rows="5" class="form-control"></textarea> ???????????????????</div> ???????????????????<div class="form-group"> ???????????????????????<input type="button" value="发布" class="btn btn-primary" id="btn-publish"> ???????????????????</div> ???????????????</form> ???????????</div> ???????????<div class="col-md-offset-3 col-md-6" id="content"> ???????????</div> ???????</div> ???</div></body><script> ???var oBtnPublish = document.getElementById("btn-publish"); ???var aTpl = [ ???????‘<div class="panel panel-success">‘, ??????????‘<div class="panel-heading">‘, ???????????????‘<h4 class="panel-title">‘, ??????????????????‘<a href="javascript:;">‘, ???????????????????‘[title]‘, ???????????????????‘</a>‘, ???????????????‘</h4>‘, ???????????‘</div>‘, ???????????‘<div class="panel-body">‘, ???????????????‘[content]‘, ???????????‘</div>‘, ???????‘</div>‘ ???]; ???var oContent = document.getElementById( "content" ), ???????str = aTpl.join( "" ), ???????title = ‘‘, content = ‘‘, panelParent = null; ???oBtnPublish.onclick = function(){ ???????str = aTpl.join( "" ); ???????title = document.getElementById( "title" ).value; ???????txt = document.getElementById( "txt" ).value; ???????str = str.replace( /\[title\]/, title ); ???????str = str.replace( /\[content\]/, txt ); ???????oContent.innerHTML += str; ???} ???oContent.onclick = function( ev ){ ???????var oEvent = ev || event; ???????var target = oEvent.target || oEvent.srcElement; ???????if ( target.tagName.toLowerCase() == ‘a‘ ) { ???????????panelParent = target.parentNode.parentNode.parentNode; ???????????if ( panelParent.children[1].style.display == "block" || ?panelParent.children[1].style.display == ‘‘ ) { ???????????????panelParent.children[1].style.display = ‘none‘; ???????????} else { ???????????????panelParent.children[1].style.display = ‘block‘; ???????????} ???????} ???}</script></html>

[js高手之路]设计模式系列课程-委托模式实战微博发布功能

原文地址:http://www.cnblogs.com/ghostwu/p/7471471.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved