日期:2014-05-16  浏览次数:20441 次

责任链模式 模拟javascript事件冒泡

在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求,并且终止传递。

javascript事件冒泡:

IE 事件由最接近事件发生坐标的html元素处发起,在事件没有被阻止的情况下,事件将跟随着该界定继承自的各个父节点冒泡穿过整个DOM节点层次

? ? ? ? FF 首先会来一个与IE相反方向的事件流,若未被catch,然后再来一个与IE相同的方向的事件流。

?

由上面可以看出事件冒泡视乎就是责任链模式的一种表现,所以做了如下的代码测试,

1. 对链上的每个元素抽象出一个接口:

?

package com.sail.utils.htmlEventFlow.dom;

import com.sail.utils.htmlEventFlow.event.JsEvent;

/**
 * 所有dom元素的接口
 * @author wjs
 *
 */
public interface Dom {

	//获取当前dom元素的名称
	String getTagName();
	
	//获取其父dom元素
	Dom getParent();
	
	//事件冒泡
	void flowEvent(JsEvent event, Dom dom);
	
	//事件处理
	void catchEvent(JsEvent event);
	
	//阻止冒泡
	boolean stopEvent();
}

?2. 生成一个通用的HTML类型Dom的模板抽象父类

?

package com.sail.utils.htmlEventFlow.dom;

import com.sail.utils.htmlEventFlow.event.JsEvent;

/**
 * HTML类型Dom模板
 * @author wjs
 *
 */
public abstract class DomHtml implements Dom {
	
	//html元素ID
	private String id;
	//html元素名称
	private String tagName;
	//html元素js处理方法
	private String eventFuntion="";

	/**
	 * 冒泡
	 * @event 事件
	 * @dom dom元素集合容器的元素
	 */
	public void flowEvent(JsEvent event, Dom dom) {
		//正向冒泡
		System.out.println(this.getTagName()+" 进行了 "+event.getType());
		//执行事件的方法
		this.catchEvent(event);
		//是否停止冒泡
		if(stopEvent())
			return ;
		//调用dom的
		dom.flowEvent(event, this);
		
		//反向冒泡,事件流
		System.out.println(this.getTagName()+" 进行了 "+event.getType()+"的事件流");
		this.catchEvent(event);
		if(stopEvent())
			return ;
	}

	public abstract Dom getParent() ;
	
	/**
	 * 模板默认处理方法
	 */
	public void catchEvent(JsEvent event) {
		if(this.eventFuntion==null || this.eventFuntion.trim().equals(""))
			System.out.println(this.getTagName()+" 未对事件 "+event.getType()+" 进行处理!");
		else{
			System.out.println(this.getTagName()+" 对事件 "+event.getType()+" 进行如下处理:");
			System.out.println(this.eventFuntion);
			System.out.println("------------------------处理结束--------------------");
		}
	}

	/**
	 * 停止冒泡
	 */
	public boolean stopEvent() {
		if(this.eventFuntion!=null && this.eventFuntion.indexOf("stopPropagation()")!=-1){
			System.out.println("--------------停止往上冒泡啦--------");
			return true;
		}
		System.out.println(this.getTagName()+" 未阻止事件冒泡");
		return false;
	}
	
	public String getEventFuntion() {
		return eventFuntion;
	}

	public void setEventFuntion(String eventFuntion) {
		this.eventFuntion = eventFuntion;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void setTagName(String tagName) {
		this.tagName = tagName;
	}
	
	public String getTagName(){
		return this.tagName;
	}

}

?4. 生成各种html元素

?

package com.sail.utils.htmlEventFlow.dom;

public class Html extends DomHtml {
	@Override
	public Dom getParent() {
		// TODO Auto-generated method stub
		return null;
	}
}


class Body extends DomHtml {
	@Override
	public Dom getParent() {
		// TODO Auto-generated method stub
		return null;
	}
}

class Table extends DomHtml {
	@Override
	public Dom getParent() {
		// TODO Auto-generated method stub
		return null;
	}
}

class Tr extends DomHtml {
	@Override
	public Dom getParent() {
		// TODO Auto-generated method stub
		return null;
	}
}

class Td extends DomHtml {

	@Override
	public Dom getParent() {
		// TODO Auto-generated method stub
		return null;
	}
}

class Div extends DomHtml {
	@Override
	public void catchEvent(JsEvent event) {
		System.out.println("--------------div通用事件处理方法-------------------");
		System.out.println(this.getTagName()+" 对事件 "+event.getType()+" 进行如下处理 :");
		System.out.println("弹出窗口");
		System.out.print