阻止浏览器默认行为,真的能阻止吗?那到底是什么样的方案,我会有这样的质疑?
那,就是它了,别看,就是你:
1
2
3
4
5
6
7
8
9
10
11
12
//阻止浏览器默认行为触发的通用方法  
function stopDefault(e){  
    //防止浏览器默认行为(W3C)  
    if(e && e.preventDefault){  
        e.preventDefault();  
    }  
    //IE中组织浏览器行为  
    else{  
        window.event.returnValue=fale; 
        return false; 
    }  
}  
没错,就是你,这个在网上一搜,基本上非常通用的解决方案,以前我也对这种方法深信不疑,觉得这是前辈们的多少次实践论证出来的东西,应该是精品,但是就在我写拖拽效果的时候,在阻止浏览器默认行为时,发现在IE8下,居然嗝屁了,
你不信?那就让我们一起来看看,上面的解决方案在IE8以下的表现吧!当然,标准浏览器是没有问题的啦,毕竟e.preventDefault() 方法还是杠杠的。
首先我们要明确一下,什么是浏览器的默认行为,举个栗子:
页面上有一行文字,如果我选中,然后拖动文字,那么文字可以被拖动,拖动后再松手,可能被选中的文字就去搜索了,由于此效果不好截图,你们自己去玩一下,那这一行为就是浏览器的默认行为;
再举个栗子:
页面上有一张图片,点击图片,然后拖动,图片会好像是复制了一份,然后也是可以被拖动,这也是浏览器的默认行为,看看IE下的截图:

这个样子的,你们应该司空见惯了吧,那浏览器厂家做的某些默认行为,我们为什么要想方设法的去阻止掉呢?因为我们在做某些效果的时候,浏览器的默认行为会影响我们的效果,比如说表单中的提交按钮,理论上的默认效果是我一点击就会将我的表单提交出去,
但现实情况可能并不希望它这样,所以我们需要阻止一下。
好了,我们来说说我们阻止浏览器的默认行为的神器吧,还是以图片和文字为例子,
<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个行为:
1、执行event.preventDefault();  阻止浏览器的默认行为;
2、event.stopPropagation();  阻止冒泡行为;
3、停止回调函数执行并立即返回。
所以用此方法的时候,必须要考虑,你是否会有阻止冒泡的需求,如果有,我们就必须要用 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()  //意思是在窗口设置鼠标捕获
额,不懂,好吧,我也不懂,那我们就用例子来描述一下:
1
2
<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;      
    }
     
    }
运行一下,感觉整个世界都平静了,再也没有纷争了,所以浏览器都表现一致,这就是一个简易的拖拽效果,这就是我给我解决方案,不知道你们是否满意呢!嘻嘻~~
当然,需要特别注意的是(多啰嗦一句):
1、如果是需要阻止所有的默认事件,那么我们用return false 和 obj.setCapture() 方法一起用;
2、如果我们仅仅只是想阻止浏览器的默认行为,可以用event.preventDefault() 与 obj.setCapture()方法一起用,这里是考虑到冒泡;
 
好了,基本上就这些了,阻止冒泡方法我也试了一下,还是挺兼容的,代码我也贴一下,换算优惠大赠送吧!
1
2
3
4
5
6
if ( e.stopPropagation ){ //标准浏览器 
    e.stopPropagation(); 
}else{ 
    //兼容IE的方式来取消事件冒泡 
    window.event.cancelBubble = true; 

以上方法只是个人意见,如有什么理解的不对的,或者是有错误的地方,欢迎批评指正,也欢迎大家跟我交流技术方面的知识,谢谢大家!