事件监听函数
<div id="box">123</div>
<script type="text/javascript">
//获得此元素
var box = document.getElementById("box");
/*
* 函数名:clickFn
* 功能:一个普通的函数,实现打印功能
*/
function clickFn(){
console.log( box.innerHTML );
}
//事件监听函数
/*
* 函数名: addEvent( obj,type,fn,capture)
* 参数
* obj: 目标元素
* type: 事件类型
* fn: 回调函数
* capture 是否异步
* 功能:主要实现事件监听
*/
function addEvent( obj,type,fn,capture ){
//console.log("aa");
if(obj.addEventListener){
obj.addEventListener("click",clickFn,true);
}else{
obj.attachEvent("click",clickFn,true);
}
}
//添加事件
addEvent(box,"click",clickFn,true);
//移除事件
/*
* 函数名:removeEvent( obj,type,fn,capture )
* 参数:
* obj 目标元素
* type 事件类型
* fn 指定事件触发调用的函数
* capture 是否同步
*/
function removeEvent( obj,type,fn,capture ){
if( obj.removeEventListener ){
obj.removeEventListener(type,clickFn,true);
}else{
obj.detachEvent("on"+ type,clickFn,true);
}
}
removeEvent(box,"click",clickFn,true);
</script>
事件冒泡的流程
js事件流(event flow ):
是指从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序,并存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
事件冒泡和事件捕获的区别:
当事件发生时,最先得到通知的
是window,然后是document,由上至下逐级依次而入,直到真正触发事件的那个元素(目标元素)为止,这个过程就是捕获。
接下来,事件会从目标元素开始起泡,由下至上逐级依次传播,直到window对象为止,这个过程就是冒泡。
所以捕获比冒泡先执行。其中DOM3级事件在DOM2的基础之上添加了更多的事件类型。
无限下拉更新图片
第一步:首先你需要获取所有img标签
var aImg = document.querySelectorAll('img');
第二步:获取地理位置信息
var scrollT = $(window).scrollTop();
var winH = $(window).height();
如果当前图片到文档顶部的距离当前浏览器的高度+滚动条距离顶部的距离,我们就加载图片
说到加载图片我们首先把图片的地址存在data-src中,加载的时候把data-src的属性赋值给src
if (aImg[i].offsetTop < scrollT + winH) {
aImg[i].src = aImg[i].getAttribute('data-src');
}复制代码
那就是这样
function loadImg() {
var scrollT = $(window).scrollTop();
var winH = $(window).height();
var aImg = document.querySelectorAll('img');
var len = aImg.length;
for (var i = 0; i < len; i++) {
if (aImg[i].offsetTop < scrollT + winH) {
aImg[i].src = aImg[i].getAttribute('data-src');
}
}
}复制代码
如果想实现下拉,加载接口下一页的数据,可以下面的方法实现
var URL = 'moubao.com/goods?page=…'
题外:下拉加载下一页的数据
function loadPage() {
var n = 0;
var len = vm.array.length;
var pageH = $(document.body).height();
var scrollT = $(window).scrollTop();
var winH = $(window).height();
var aa = (pageH - winH - scrollT) / winH;
if (aa < 0.5) {
getData(i);
}
flag = false;
}
注:getData()函数
function getData(pagenumber){
i++
$.ajax({
type: 'get',
url: URL,
data: { page: pagenumber, size: gPageSize },
dataType: 'json',
success: function(ajaxData) {
console.log(ajaxData);
},
});
}
不过在调用loadImg()的时候,别直接写loading(),放在例如
$(‘window’).scroll(functin(){
loagImg();
loadPage();
});
因为,两个函数都要实时获取到
$(document.body).height();
$(window).scrollTop();
$(window).height();
事件绑定
首先,我先来介绍我们平时绑定事件的三种方法。
1.嵌入dom
<button onclick="open()">按钮</button>
<script>
function open(){
alert(1)
}
</script>
2.直接绑定
<button id="btn">按钮</button>
<script>
document.getElementById('btn').onclick = function(){
alert(1)
}
3.事件监听
<button id="btn">按钮</button>
<script>
document.getElementById('btn').addEventListener('click',function(){
alert(1)
})
//兼容IE
document.getElementById('btn').attachEvent('click',function(){
alert(1)
})
事件委托
对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只制定一个事件处理程序,就可以管理某一类型的所有事件。例如click事件一直会冒泡到document层。也就是我们可以只指定onclick事件处理程序,而不必给每个事件分别添加处理程序。
样式以及DOM结构
<style>
* {
padding: 0;
margin: 0;
}
.head, li div {
display: inline-block;
width: 70px;
text-align: center;
}
li .id, li .sex, .id, .sex {
width: 15px;
}
li .name, .name {
width: 40px;
}
li .tel, .tel {
width: 90px;
}
li .del, .del {
width: 15px;
}
ul {
list-style: none;
}
.user-delete {
cursor: pointer;
}
</style>
</head>
<body>
<div id="J_container">
<div class="record-head">
<div class="head id">序号</div><div class="head name">姓名</div><div class="head sex">性别</div><div class="head tel">电话号码</div><div class="head province">省份</div><div class="head">操作</div>
</div>
<ul id="J_List">
<li><div class="id">1</div><div class="name">张三</div><div class="sex">男</div><div class="tel">13788888888</div><div class="province">浙江</div><div class="user-delete">删除</div></li>
<li><div class="id">2</div><div class="name">李四</div><div class="sex">女</div><div class="tel">13788887777</div><div class="province">四川</div><div class="user-delete">删除</div></li>
<li><div class="id">3</div><div class="name">王二</div><div class="sex">男</div><div class="tel">13788889999</div><div class="province">广东</div><div class="user-delete">删除</div></li>
</ul>
</div>
</body>
不用事件委托。而这种方法造成的代价是,性能的大量浪费。如果是成千上万条数据,页面将会严重卡顿,甚至崩溃。
function Contact(){
this.init();
}
Contact.prototype.init = function(){
var userdel = document.querySelectorAll('.user-delete');
for(var i=0;i<lis.length;i++){
(function(j){
userdel[j].onclick = function(){
userdel[j].parentNode.parentNode.removeChild(userdel[j].parentNode);
}
})(i);
}
}
new Contact();
使用事件委托,只绑定一次事件,大大减少了性能的损耗。也是在需要大量事件处理程序中一种非常好的解决方式。
function Contact(){
this.init();
}
Contact.prototype.init = function(){
var lis = document.querySelector('#J_List');
lis.addEventListener('click', function(e){
var target = e.target || e.srcElement;
if (!!target && target.className.toLowerCase()==='user-delete') { target.parentNode.parentNode.removeChild(target.parentNode);
}
})
}
new Contact(
);