HTML中动态生成内容的事件绑定问题

        在实际开发过程中,有时需要向页面中动态的插入html内容,并在插入的节点中绑定事件处理函数。

        用Javascript向HTML文档中插入内容,有两种方法,一种是JS创建节点,然后插入到html中;另外一种是通过ajax异步加载的方式,从服务器获取数据,然后用js把获取的数据经过处理后插入html中。

<1> JS创建节点插入html中

<div id="a">
	<ul>
		<li>行1</li>
		<li>行2</li>
		<li>行3</li>
	</ul>
</div>

<script type="text/javascript">
	var ele = document.createElement("p");
	ele.innerHTML = "这是插入的内容";
	document.getElementById("a").appendChild(ele);
	var tag = document.getElementById("a").getElementsByTagName("p");
	for (var i = 0;i < tag.length;i++)
	{
		tag[i].οnclick=function()
		{
			console.log("Click Event!");
		}
	}
</script>

        页面会生成一个p标签并且点击p标签控制台会输出Click Event!毫无疑问js代码和html顺序不可更改,因为页面还没加载到页面内容。可以用以下jquery版本测试:

<script type="text/javascript">
    $(function()
    {
        $("p").click(function()
        {
            console.log("Click!");
        })    
        $("<p>这是生成的内容</p>").appendTo("#a");
    })
</script>
        这个时候其实我们已经得出结论了,当需要的内容还没有被插入时,选择器只会选择页面中已经存在的元素,所以事先没有存在元素是绑定不了事件的。

        但是,实际情况是,工作中有可能需要把后来生成的元素绑定上事件,并注册上事件处理函数。例如本网站的留言系统,第一次加载只会显示固定条数的评论,如果评论超过一定数量,剩下的会用ajax的方式进行加载。所有的留言最后都有个回复功能,点击可以恢复相应的留言,也就是说,动态加载上来的留言,也许要绑定click事件,并注册上回复留言的函数。当然偷懒的方法是,为ajax加载上来的内容再注册一个click并再绑定一次相应的函数,但这加大了代码的冗余度,增加系统开销,还会使代码变得难以理解。那么更好的解决办法是什么呢?
留言系统的回复功能

留言系统的回复功能

可以这样理解,无论HTML内容是不是JS生成的,只要没有跨域,所有页面内的元素都属于这个页面,都能够绑定事件,JS中有个非常重要的概念叫事件冒泡,简单来讲,就是子元素产生的事件,会一直冒泡到最顶级父元素,并能够被父元素监测到。请看下图:
事件冒泡

事件冒泡

那么,我能不能在被插入元素的父元素上监测冒泡产生的事件,并回调相应的函数呢?答案是当然是肯定的。来看下面的例子,注意网页面里插入内容是在JS代码的最后。


    $(function(){
        $("body").delegate("p","click",function(){
            console.log("Click Event");
        })    
        $("<p>这是生成的内容</p>").appendTo("body");
    })


这是,发现所有的P元素点击都产生了输出,说明代码运行成功。这里我们用到了jQuery的delegate函数,来看一下官方解释:

    Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.
    根据特定的根元素,把一个或者多个事件注册到指定的元素上,不论这个元素现在是否存在。

在jQuery1.7.3以上的版本中,on方法也可以做这件事,官方有示例说明,这里不再赘述。
jQuery提供一个强大的API来解决这个问题,原生的JS怎么去做呢?下面给出一个简单方案,希望能对大家理解冒泡的原理有所帮助。

    <script>
    function gelegate(action,selector,callback){
        document.addEventListener(action,function(e){
            if(selector==e.target.tagName.toLowerCase()||selector==e.target.className){
                console.log("Click Event");
                callback();
            }
        })
    }
    gelegate('click','p',function(){});
    var appendhtml=document.createElement("p");
    appendhtml.innerHTML="这是插入的内容";
    document.body.appendChild(appendhtml);
    </script>

注意,以上代码仅针对chrome,实际项目可能会产生兼容性问题。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值