看到这标题,是否是有点逆天的感受,总感受好狂拽炫酷,耳边隐隐约约传来一个声音:你这么叼,你咋不上天呢! ~~ 额,好吧!javascript
话入正题,我为何会提出这么一个问题呢?html
阻止浏览器默认行为,真的能阻止吗?那究竟是什么样的方案,我会有这样的质疑?java
那,就是它了,别看,就是你:chrome
//阻止浏览器默认行为触发的通用方法 function stopDefault(e){ //防止浏览器默认行为(W3C) if(e && e.preventDefault){ e.preventDefault(); } //IE中组织浏览器行为 else{ window.event.returnValue=fale; return false; } }
没错,就是你,这个在网上一搜,基本上很是通用的解决方案,之前我也对这种方法深信不疑,以为这是前辈们的多少次实践论证出来的东西,应该是精品,可是就在我写拖拽效果的时候,在阻止浏览器默认行为时,发如今IE8下,竟然嗝屁了,浏览器
你不信?那就让咱们一块儿来看看,上面的解决方案在IE8如下的表现吧!固然,标准浏览器是没有问题的啦,毕竟e.preventDefault() 方法仍是杠杠的。函数
首先咱们要明确一下,什么是浏览器的默认行为,举个栗子:this
页面上有一行文字,若是我选中,而后拖动文字,那么文字能够被拖动,拖动后再松手,可能被选中的文字就去搜索了,因为此效果很差截图,大家本身去玩一下,那这一行为就是浏览器的默认行为;spa
再举个栗子:线程
页面上有一张图片,点击图片,而后拖动,图片会好像是复制了一份,而后也是能够被拖动,这也是浏览器的默认行为,看看IE下的截图:htm
这个样子的,大家应该司空见惯了吧,那浏览器厂家作的某些默认行为,咱们为何要千方百计的去阻止掉呢?由于咱们在作某些效果的时候,浏览器的默认行为会影响咱们的效果,好比说表单中的提交按钮,理论上的默认效果是我一点击就会将个人表单提交出去,
但现实状况可能并不但愿它这样,因此咱们须要阻止一下。
好了,咱们来讲说咱们阻止浏览器的默认行为的神器吧,仍是以图片和文字为例子,
<img src="1.jpg" id="img1" alt=""> <p id="text">圣诞节开发能顺利的烦恼时来得快耐腐蚀的快乐你发了十多年两三点扣年费是考虑到你发来看你</p>
这是咱们页面上的一张图和一行文字,随便打的
window.onload = function(){ var oImg = document.getElementById("img1"); var oText = document.getElementById("text"); oImg.onmousedown = function(e){ stopDefault(e); } oText.onmousedown = function(e){ stopDefault(e); } //阻止浏览器默认行为触发的通用方法 function stopDefault(e){ //防止浏览器默认行为(W3C) if(e && e.preventDefault){ e.preventDefault(); } //IE中组织浏览器行为 else{ window.event.returnValue=false; //实际上在IE8如下,会报错 return false; } } }
这是用咱们的神器来写的一个小例子,意思是当鼠标按下去的时候,咱们来阻止浏览器的默认行为,看看都有什么表现,若是图片和文字不能被拖动,说明是能够阻止默认行为的,若是不能,呵呵,你就惨了~
在标准浏览器上,good,没问题,完美,在IE上,IE9以上good,IE8下,呃呃(此处有音效),嗝屁了,它们依然快乐的处处游走,跟它们就没什么关系,因而可知,上面的神器是不足以来知足咱们的要求的(毁三观啊)~
那如今的问题就变了,怎样才能全面兼容阻止浏览器的默认行为呢?这就是标题的后半段要讲的内容了(主角来了)!
首先,咱们要确定的是 e.preventDefault() 方法是绝对能够在标准浏览器下阻止默认行为的,可是(重点来了),咱们今天不用这个方法,而是用 return false 这个熟悉的老朋友,固然关于return ,咱们又能够讲一篇长长的博文,像老太太的裹脚布同样,
这里咱们不讲多么的详细,就提几点:
return 表达式是结束函数执行,返回调用函数,没有返回结果,举个栗子:
function adc(){ var a=2; var b=3; var sum = 0; return ; sum = a+b; console.log(sum); } adc();
看上面的这个函数,若是没有return,那么console就会打印sum的值5,可是偏偏有个return,让函数在return后就不往下执行,而是返回到调用函数,因此就没有值了,
那么return false呢,通常是返回错误的处理结果;终止处理;阻止提交表单;阻止执行默认的行为等等,值得注意的是,执行return false,实际上是执行了3个行为:
一、执行event.preventDefault(); 阻止浏览器的默认行为;
二、event.stopPropagation(); 阻止冒泡行为;
三、中止回调函数执行并当即返回。
因此用此方法的时候,必需要考虑,你是否会有阻止冒泡的需求,若是有,咱们就必需要用 event.preventDefault();来阻止浏览器的默认行为了,咱们仍是来举个栗子吧(一贯的风格就是例子胜于雄辩):
window.onload = function(){ var oImg = document.getElementById("img1"); var oText = document.getElementById("text"); oImg.onmousedown = function(e){ return false; } oText.onmousedown = function(e){ return false; } }
仍是用上面的例子,改写一下,看看效果如何, 恩,标准浏览器,杠杠的,再看IE,IE9以上依旧如此完美,IE8如下依旧那么飘逸,好吧,看来咱们要解决的梗就是如何使IE8如下浏览器能乖一点!
要解决这个问题,我先介绍一个方法(闪亮登场):
setCapture() //意思是在窗口设置鼠标捕获
额,不懂,好吧,我也不懂,那咱们就用例子来描述一下:
<input type="button" value="按钮一"> <input type="button" value="按钮二">
页面上有2个按钮
window.onload = function(){ var aInput = document.getElementsByTagName("input"); //设置全局捕获,当咱们给一个元素设置全局捕获后,这个元素就会监听后续的全部事件,当有事件发生的时候,就会被当前设置了全局捕获的元素所触发 /* ie : 有,而且有效果 ff : 有,但没有效果 chrome : 没有,会报错 */ aInput[0].setCapture(); aInput[0].onclick = function(){ alert(1); }; aInput[1].onclick = function(){ alert(2); } }
分别给2个按钮设点击事件,而且给按钮一开一个小灶,给它设一个全局的鼠标捕获,咱们来看看,谷歌下,会报错,不支持,火狐下,没有报错,也没有别的什么反应,一切正常,说明火狐是支持的,只是没反应(由于不报错),IE下,怪异状况就出现了
不管个人鼠标在哪里点击,都会弹出1,就算是点击按钮2,也会弹出1,点到窗口外,也会弹出1,这是为何呢?我查了一下资料,大概的解释是:
函数功能:该函数在属于当前线程的指定窗口里设置鼠标捕获。一旦窗口捕获了鼠标,全部鼠标输入都针对该窗口,不管光标是否在窗口的边界内。同一时刻只能有一个窗口捕获鼠标。若是鼠标光标在另外一个线程建立的窗口上,只有当鼠标键按下时系统才将鼠标输入指向指定的窗口。
通俗的意思是:当某个元素设置了全局鼠标捕获,那个这个元素就会监听后续发生的因此事件,当有事件发生的时候,就会被当前设置了全局捕获的元素触发,
因此,咱们看上面例子的怪异表现,当鼠标点击的时候,就会被绑定了全局捕获的按钮一所触发,那会执行按钮一的点击事件,因此会弹出1;
那么它是怎么来阻止浏览器的默认行为的呢?举个栗子:
window.onload = function(){ var oImg = document.getElementById("img1"); var oText = document.getElementById("text"); oImg.onmousedown = function(e){ oImg.setCapture(); } oText.onmousedown = function(e){ oText.setCapture(); } }
咱们都知道这个在标准浏览器上是不行的,咱们暂时无论,只看IE的,你会发现,在IE上,一会儿就老实了,不再处处跑了,这是为何呢?用上面的解释就是,由于此时图片和文字都设了全局鼠标捕获,无论页面上有什么事件发生,都会转移到它们身上,咱们又
没有给它们写move事件,因此就很乖乖的在那里不动了,明白了吗?
那咱们给图片加个自定义的move事件,看看会怎样?(此时这里的图片是绝对定位的,样式我就不写了)
window.onload = function(){ var oImg = document.getElementById("img1"); oImg.onmousedown = function(ev){ var ev = ev || event; var disX = ev.clientX - this.offsetLeft; var disY = ev.clientY - this.offsetTop; if(oImg.setCapture){ oImg.setCapture(); } document.onmousemove = function(ev){ var ev = ev || event; oImg.style.left = ev.clientX - disX + 'px'; oImg.style.top = ev.clientY - disY + 'px'; }; document.onmouseup = function(ev){ document.onmousemove = document.onmouseup = null; if(oImg.releaseCapture){ //取消全局捕获 oImg.releaseCapture(); } }; return false; } }
运行一下,感受整个世界都平静了,再也没有纷争了,因此浏览器都表现一致,这就是一个简易的拖拽效果,这就是我给我解决方案,不知道大家是否满意呢!嘻嘻~~
固然,须要特别注意的是(多啰嗦一句):
一、若是是须要阻止全部的默认事件,那么咱们用return false 和 obj.setCapture() 方法一块儿用;
二、若是咱们仅仅只是想阻止浏览器的默认行为,能够用event.preventDefault() 与 obj.setCapture()方法一块儿用,这里是考虑到冒泡;
好了,基本上就这些了,阻止冒泡方法我也试了一下,仍是挺兼容的,代码我也贴一下,换算优惠大赠送吧!
if ( e.stopPropagation ){ //标准浏览器 e.stopPropagation(); }else{ //兼容IE的方式来取消事件冒泡 window.event.cancelBubble = true; }
以上方法只是我的意见,若有什么理解的不对的,或者是有错误的地方,欢迎批评指正,也欢迎你们跟我交流技术方面的知识,谢谢你们!
ps:若是你看过我写的pc拖拽效果,请看的时候参考一下本文,哪里的阻止默认事件写错了,记得修改!