无需申请自动送彩金68_白菜送彩金网站大全[无需申请秒送彩金]
做最好的网站
来自 无需申请自动 2019-07-18 19:39 的文章
当前位置: 无需申请自动送彩金68 > 无需申请自动 > 正文

javascript事件委托的方式绑定详解,JS动态创建D

本文实例讲述了Javascript监视变量变化的方法。分享给大家供大家参考。具体分析如下:

js事件绑定

本文实例讲述了JS动态创建DOM元素的方法。分享给大家供大家参考。具体如下:

无需申请自动送彩金68,大家应该知道,在C#中对于属性、文件等的更改监视非常简单,因为有委托(事件)、FileSystemWatcher等好东东扶持。

事件绑定,这里使用了冒泡的原理,从点击的元素开始,递归方式的向父元素传播事件,这样做的好处是对于大量要处理的元素,不必为每个元素都绑定事件,只需要在他们的父元素上绑定一次即可,提高性能。还有一个好处就是可以处理动态插入dom中的元素,直接绑定的方式是不行的。

近日,因工作需要,需要通过点击某个元素后, 动态创建一个DOM元素并显示,因此写了一些相关的JS函数,在此记录,以作备忘:

那么在JavaScript中,如何对变量的更改进行监视呢?首先,我仿照c#的属性来对JS进行操作,写出了如下的示例:

之前一直使用的是jquery的on方法做这样的事情,前几天看到公司项目中有实现这种方式的源代码,拿来仔细研究研究,跟大家分享分享。

/*
动态创建DOM元素的相关函数支持
*/
/*
获取以某个元素的DOM对象
@obj 该元素的ID字符串
*/
function getElement(obj)
{
  return typeof obj=='string'?document.getElementById(obj):obj;
}
/*
获取某个元素的位置
@obj 该元素的DOM对象,或该元素的ID
*/
function getObjectPosition(obj)
{
  obj=typeof obj==='string'?getElement(obj):obj;
  if(!obj)
  {
   return;
  } 
  var position='';
  if(obj.getBoundingClientRect) //For IEs
  {
   position=obj.getBoundingClientRect();
   return {x:position.left,y:position.top};
  }
  else if(document.getBoxObjectFor)
  {
   position=document.getBoxObjectFor(obj);
   return {x:position.x,y:position.y};
  }
  else
  {
   position={x:obj.offsetLeft,y:obj.offsetTop};
   var parent=obj.offsetParent;
   while(parent)
   {
    position.x =obj.offsetLeft;
    position.y =obj.offsetTop;
    parent=obj.offsetParent;
   }
   return position;
  }
}
/*
为某个DOM对象动态绑定事件
@oTarget 被绑定事件的DOM对象
@sEventType 被绑定的事件名,注意,不加on的事件名,如 'click'
@fnHandler 被绑定的事件处理函数
*/
function addEventHandler(oTarget, sEventType, fnHandler)
{
   if (oTarget.addEventListener) 
   {
     oTarget.addEventListener(sEventType, fnHandler, false);
   } 
   else if (oTarget.attachEvent) //for IEs
   {
     oTarget.attachEvent("on"   sEventType, fnHandler);
   } 
   else 
   {
     oTarget["on"   sEventType] = fnHandler;
   }
}
/*
从某个DOM对象中去除某个事件
@oTarget 被绑定事件的DOM对象
@sEventType 被绑定的事件名,注意,不加on的事件名,如 'click'
@fnHandler 被绑定的事件处理函数
*/
function removeEventHandler(oTarget,sEventType,fnHandler)
{
   if(oTarget.removeEventListener) 
   {
    oTarget.removeEventListener(sEventType,fnHandler,false)
   }
   else if(oTarget.detachEvent) //for IEs
   {
    oTarget.detachEvent(sEventType,fnHandler);
   }
   else
   {
    oTarget['on' sEventType]=undefined;
   }
}
/*
创建动态的DOM对象
@domParams是被创建对象的属性的JSON表达,它具有如下属性:
@parentNode 被创建对象所属的父级元素(可为元素ID,也可为DOM对象)
@domId 被创建对象的ID
@domTag 被创建对象的tag名称,支持常用的布局元素,如div span等,但不支持inputform等特别的元素 
@content 被创建的对象内容 
@otherAttributes 为被创建的对象添加除函数必需的属性外其它属性,如[{attrName:'style.color',attrValue:'red'}]
@eventRegisters 为被创建的对象添加事件,类似[{eventType:'click',eventHandler:adsfasdf}]的数组
-经过组合后,该参数具有如下形式:
{parentNode:document.body,domTag:'div',content:'这是测试的',otherAttributes:[{attrName:'style.color',attrValue:'red'}],eventRegisters:[{eventType:'click',eventHandler:fnHandler}]}
*/
function dynCreateDomObject(domParams)
{ 
  if(getElement(domParams.domId))
  {
   childNodeAction('remove',domParams.parentNode,domParams.domId);
  }
  var dynObj=document.createElement(domParams.domTag);
  with(dynObj)
  {  
  //id也可以通过otherAttributes传入,但是出于ID的特殊性,此处仍然采用
  //JSON对象传入,并以DOM ID属性附件
   id=domParams.domId;
   innerHTML=domParams.content;
   //innerHTML是DOM属性,而id等是元素属性,注意区别
  }
  /*添加属性*/
  if(null!=domParams.otherAttributes)
  {
   for(var i=0;i<domParams.otherAttributes.length;i  )
   {    
    var otherAttribute =domParams.otherAttributes[i];
    dynObj.setAttribute(otherAttribute.attrName,otherAttribute.attrValue);
   }
  }
  /*end 添加属性*/
  /*添加相关事件*/
  if(null!=domParams.eventRegisters)
  {
   for(var i=0;i<domParams.eventRegisters.length;i  )
   {
    var eventRegister =domParams.eventRegisters[i];    
    addEventHandler(dynObj,eventRegister.eventType,eventRegister.eventHandler);
   }
  }
  /*end 添加相关事件*/ 
  try
  {   
    childNodeAction('append',domParams.parentNode,dynObj);
  }
  catch($e)
  {
  } 
  return dynObj;
}
/*
从父结点中删除子结点
@actionType 默认为append,输入字符串 append | remove
@parentNode 父结点的DOM对象,或者父结点的ID
@childNode 被删除子结点的DOM对象 或者被删除子结点的ID
*/
function childNodeAction(actionType,parentNode,childNode)
{
 if(!parentNode)
 {return; }
 parentNode=typeof parentNode==='string'?getElement(parentNode):parentNode;
 childNode=typeof childNode==='string'?getElement(childNode):childNode;
 if(!parentNode || !childNode)
 {return;}
 var action=actionType.toLowerCase();
 if( null==actionType || action.length<=0 || action=='append')
 {
  action='parentNode.appendChild';
 }
 else
 {
  action='parentNode.removeChild';
 }

 try
 {
  eval(action)(childNode);
 }
 catch($e)
 {
  alert($e.message);  
 }
}
function Class1()
{
  var oldValue='';
  var name='xu';
  var id='1';
  this.setName=function(n)
  {
   oldValue=name;
   name=n;
   this.propertyChange('name',oldValue,n);
 }
 this.setID=function(n)
 {
   oldValue=id;
   id=n;
   this.propertyChange('id',oldValue,n);
 }
 this.display=function()
 {
   alert(name ''s id is :' id);
 }
}
Class1.prototype={
 propertyChange:function(propertyName,oldValue,newValue)
 {
   alert(propertyName ''s value changed from ' oldValue ' to ' newValue); 
 }
};
var c=new Class1();
c.setName('xu22');
c.setID('5');
c.display();
function $bindAction(dom, event, listeners) {
 #这里的dom为绑定事件的元素,比如document.body
 #event为绑定的事件,比如click
 #listeners是待执行的事件对象
 $addEvent(dom, event, function(e) {
 #这里获取事件e
 #获取点击的元素src
 var e = e || window.event,
  src = e.target || e.srcElement,
  action,
  returnVal;

 #模拟冒泡的方式,先是src,然后是src.parentNode,再然后是src.parentNode.parent.Node
 #当前dom元素等于事件绑定的dom元素的时候,停止“冒泡”
 while (src && src !== dom) {
  #循环获取dom元素的attr-action属性,
  action = src.getAttribute('attr-action');
  #如果当前dom元素存在attr-action属性,并且事件对象中有该属性值的函数,执行这个函数
  #将事件e、当前dom元素、元素的属性attr-action值传给要执行的函数
  if (listeners[action]) {
  returnVal = listeners[action]({
   src : src,
   e : e,
   action : action
  });
  #如果上面的函数执行之后返回false,停止继续“冒泡”
  if (returnVal === false) {
   break;
  }
  }
  #获取当前dom元素的父元素节点
  src = src.parentNode;
 }
 });
};

function $addEvent(obj, type, handle) {
 if(!obj || !type || !handle) {
 return;
 }
 #绑定事件到多个对象,递归调用
 if( obj instanceof Array) {
 for(var i = 0, l = obj.length; i < l; i  ) {
  $addEvent(obj[i], type, handle);
 }
 return;
 }
 #绑定多个事件,递归调用
 if( type instanceof Array) {
 for(var i = 0, l = type.length; i < l; i  ) {
  $addEvent(obj, type[i], handle);
 }
 return;
 }
 #下面这一大段用来记录当前页面一共绑定了多少个事件,以及事件的相关信息
 #以及某个对象上面绑定的事件id
 window.__allHandlers = window.__allHandlers || {};
 window.__Hcounter = window.__Hcounter || 0;
 function setHandler(obj, type, handler, wrapper) {
 obj.__hids = obj.__hids || [];
 var hid = 'h'     window.__Hcounter;
 obj.__hids.push(hid);
 window.__allHandlers[hid] = {
  type : type,
  handler : handler,
  wrapper : wrapper
 }
 }
 #这个里面的apply是为了修改绑定事件所执行函数中的this
 #这个在低版本的IE中才真正起作用
 function createDelegate(handle, context) {
 return function() {
  return handle.apply(context, arguments);
 };
 }

 #绑定事件,记录事件绑定信息
 if(window.addEventListener) {
 var wrapper = createDelegate(handle, obj);
 setHandler(obj, type, handle, wrapper)
 obj.addEventListener(type, wrapper, false);
 }
 else if(window.attachEvent) {
 var wrapper = createDelegate(handle, obj);
 setHandler(obj, type, handle, wrapper)
 obj.attachEvent("on"   type, wrapper);
 }
 else {
 obj["on"   type] = handle;
 }
};

使用示例:

将对对象内部变量(私有变量)的赋值操作提取到了方法中,而在该方法中触发相应的变量值更改回调方法。

看个例子:

var htmlAttributes=
[
{attrName:'class',attrValue:'样式名称' } //for IEs
,
{attrName:'className',attrValue: '样式名称'} //for ff
]  
var domParams={domTag:'div',content:'动态div的innerHTML',otherAttributes:htmlAttributes};
var newHtmlDom=dynCreateDomObject(domParams);
//通过 setAttribute('style','position:absolute.....................')
//的形式来指定style没有效果,只能通过如下形式,jiong
newHtmlDom.style.zIndex='8888';
newHtmlDom.style.position='absolute';
newHtmlDom.style.left='100px';
newHtmlDom.style.top='200px';

本文由无需申请自动送彩金68发布于无需申请自动,转载请注明出处:javascript事件委托的方式绑定详解,JS动态创建D

关键词: