JavaScript(11): event proxy

In JavaScript, event proxy, also known as event delegate, is to bind the listening event of the child object to the parent object of the event source object and trigger the event by using the event bubble principle.
Advantages:
  1. Improve performance without binding events to all objects;
  2. Flexible and dynamically created new objects do not need to bind events.
Disadvantages:
1. Some processes are inconvenient and may affect the speed, such as mouse in and mouse out on the object;
2. It is necessary to selectively prevent event bubbling.

1. Capture and bubbling

Bubbling of events: events are passed from the bottom of the DOM tree to the root node of the dom.
Event capture: events are passed from the root node of the DOM tree to the bottom layer of the dom.
Prevent bubbling events:
W3C standard: event stopPropagation(); Versions below IE9 are not supported

2. Event source object
It is used to obtain the detailed information of the event, such as the status of the keyboard and mouse, the object clicked by the mouse, etc.

3. Mount event monitoring
  domObj.addEventListener(eventType,func,eventModule)
eventType: event type without on
func: callback function after event
eventModule: boolean value, which represents the event model, false represents the bubbling model, and true represents the code capture model. The default is false.

4. Examples

In JavaScript(10): the gradual separation of structure, style and behavior, there are examples of tables. You can also rewrite the script to refine the code, that is, two loops are used.

Actual result chart:

Web file content:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="X-UA-Compatible" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript Event agent</title>
    <link rel="stylesheet" href="JavaScript Event agent.css">
    <script src="JavaScript Event agent.js"></script>
</head>
<body onload="init()">
  <div id="demo">
    <h1 align="center">Student transcript</h1>
    <table align="center" class="table" bgcolor="#cccccc" id="studentTable">
        <tr class="rowTitleColorSet">
            <td>Student number</td>
            <td>full name</td>
            <td>language</td>
            <td>mathematics</td>
            <td>average</td>
            <td>operation</td>
        </tr>
    </table>        
  </div>
</body>
</html>

Style file JavaScript event proxy css

body{
     font-family:Arial,Helvetica,sans-serif;
	 font:24px "Microsoft YaHei ";
}
.table {
	cellpadding:1;
	cellspacing:1;
}
.table tr{
	line-height:200%;
}        

.table td{
	width: 100px;
}

.rowTitleColorSet{background-color: #818080;color: rgb(232, 232, 232);text-align: center;}
.evenRowColorSet{background-color: #efefef;color: rgb(8, 8, 8);text-align: center}
.oddRowColorSet{background-color: #f8f8f8;color: rgb(128, 128, 128);text-align: center}
.focusRowColorSet{background-color: #999;color:#d70008;text-align: center}

Code file JavaScript event proxy:

  function init(){
        //Create studentList object
        var studentList=[
                        {Id:101,Name:'Xiao Ming',ChineseScore:81.5,MathScore:87},
                        {Id:102,Name:'Xiao Huang',ChineseScore:61,MathScore:47.5},
                        {Id:103,Name:'Xiao Li',ChineseScore:89.5,MathScore:83},
                        {Id:104,Name:'Xiao Song',ChineseScore:56,MathScore:97},
                        {Id:105,Name:'Xiao Wang',ChineseScore:82,MathScore:73},
                        {Id:106,Name:'petty thief',ChineseScore:31,MathScore:63},
                        {Id:107,Name:'Xiaohua',ChineseScore:49,MathScore:83},
                    ]       
	    var table=document.getElementById("studentTable");
		for(i in studentList){
            var trTemp=document.createElement("tr");//Create row object
            //Set line style
            if(parseInt(i)%2==0){
                trTemp.className="evenRowColorSet"
            }else{
                trTemp.className="oddRowColorSet"
            }
            //Add event response to row
            trTemp.onmouseenter=funcMouseenter;//Mouse in event
            trTemp.onmouseout=funcMouseout;//Mouse out event			
			//Add td object
			for(item in studentList[i]){
				//Create td
				var tdTmp=document.createElement("td");
				tdTmp.style="width: 100px;";
				tdTmp.appendChild(document.createTextNode( studentList[i][item] ));
				trTemp.appendChild(tdTmp);				
			}
			//Increase average score
            var tdAverageScore=document.createElement("td");
			tdAverageScore.style="width: 100px;";
            AverageScore=(studentList[i].MathScore+studentList[i].MathScore)/2;
            tdAverageScore.appendChild(document.createTextNode( AverageScore ));			
			trTemp.appendChild(tdAverageScore);	
			//Add operation bar
            var tdbtn=document.createElement("td");
			tdbtn.style="width: 100px;";
			var btn=document.createElement('input');
			btn.type="button";
			btn.id=item;
			btn.value="delete";
			btn.onclick=function(){ del(this); };
			//Add to row object
            trTemp.appendChild( btn );			
			//Add to table object
			table.appendChild(trTemp);
		}
}
		
function funcMouseenter(event){
	this.className='focusRowColorSet'
}

function funcMouseout(event){
	var studentID=this.cells[0].innerHTML;        
	if(parseInt(studentID)%2==0){
			this.className="evenRowColorSet"
	}else{
			this.className="oddRowColorSet"
	}
}

function del(obj){
	 var tr = obj.parentNode;
	 var studentID=tr.cells[0].innerHTML;
	 var flag = confirm("Confirm to delete student number as" + studentID + "Record?");
	 if(flag) {//confirm deletion
				//Delete student ID: delfromdb (studentID) from the database
				tr.parentNode.removeChild(tr);//Delete tr
	 }
	 //return false
}

The performance of the browser can be affected by too many delegated events, because the browser can use the JavaScript event queuing mechanism to listen to all these events.

Use event delegate to rewrite the script file JavaScript event proxy js:

  function init(){
        //Create studentList object
        var studentList=[
                        {Id:101,Name:'Xiao Ming',ChineseScore:81.5,MathScore:87},
                        {Id:102,Name:'Xiao Huang',ChineseScore:61,MathScore:47.5},
                        {Id:103,Name:'Xiao Li',ChineseScore:89.5,MathScore:83},
                        {Id:104,Name:'Xiao Song',ChineseScore:56,MathScore:97},
                        {Id:105,Name:'Xiao Wang',ChineseScore:82,MathScore:73},
                        {Id:106,Name:'petty thief',ChineseScore:31,MathScore:63},
                        {Id:107,Name:'Xiaohua',ChineseScore:49,MathScore:83},
                    ]       
	    var table=document.getElementById("studentTable");
		for(i in studentList){
            var trTemp=document.createElement("tr");//Create row object
            //Set line style
            if(parseInt(i)%2==0){
                trTemp.className="evenRowColorSet"
            }else{
                trTemp.className="oddRowColorSet"
            }
			//Add td object
			for(item in studentList[i]){
				//Create td
				var tdTmp=document.createElement("td");
				tdTmp.style="width: 100px;";
				tdTmp.appendChild(document.createTextNode( studentList[i][item] ));
				trTemp.appendChild(tdTmp);				
			}
			//Increase average score
            var tdAverageScore=document.createElement("td");
			tdAverageScore.style="width: 100px;";
            AverageScore=(studentList[i].MathScore+studentList[i].MathScore)/2;
            tdAverageScore.appendChild(document.createTextNode( AverageScore ));			
			trTemp.appendChild(tdAverageScore);	
			//Add operation bar
            var tdbtn=document.createElement("td");
			tdbtn.style="width: 100px;";
			var btn=document.createElement('input');
			btn.type="button";
			btn.id=item;
			btn.value="delete";
			//Add to row object
            trTemp.appendChild( btn );			
			//Add to table object
			table.appendChild(trTemp);
		}
		
	  var oldSelectRow;
	  var currentSelectRow;
	  table.addEventListener('click',function(e){
		  if(e.target.type=='button'){
			 var tr = e.target.parentNode;
			 var studentID=tr.cells[0].innerHTML;
			 var flag = confirm("Confirm to delete student number as" + studentID + "Record?");
			 if(flag) {//confirm deletion
				//Delete student ID: delfromdb (studentID) from the database
				tr.parentNode.removeChild(tr);//Delete tr
			 }			
		  }
	  })
	  
	  table.addEventListener('mouseover',function(e){//Move the mouse within the table
		  if(e.target.parentElement.rowIndex){
			    //Move on a table row
			    currentSelectRow=e.target.parentElement;//Get the current row object and record it
				e.target.parentElement.className="focusRowColorSet";//Sets the current row as the focus row								
				if(currentSelectRow!=oldSelectRow){
					if(oldSelectRow){
						trIndex=oldSelectRow.rowIndex;//Get the line number of the current line object
						if(parseInt(trIndex)%2==0){
								oldSelectRow.className="evenRowColorSet";
						}else{
								oldSelectRow.className="oddRowColorSet";
						}						
					}
					oldSelectRow=currentSelectRow;
				}			  
		  }
	  })
	  
	  table.addEventListener('mouseout',function(e){//Mouse out of table event
		  if(currentSelectRow){
			var trIndex=currentSelectRow.rowIndex;//Get the line number of the current line object
			if(parseInt(trIndex)%2==0){
					currentSelectRow.className="evenRowColorSet";
			}else{
					currentSelectRow.className="oddRowColorSet";
			}									  
		  }
		  oldSelectItem=null;
		  currentSelectItem=null;
	  })	  
}

The rewriting of the above code completes the same function, that is, it uses the principle of event delegation. This has obvious advantages and disadvantages, which may cause Caton phenomenon, and the script is not easy to debug. Such a simple rewriting took me more than half an hour.

Keywords: Javascript Front-end

Added by bizshop on Sat, 12 Feb 2022 15:05:30 +0200