ASP.NET AJAX(12)__浏览器兼容功能判断浏览器的类型和版本Sys.Browser针对DOM元素的兼容操作针对DOM事件的兼容操作

目前,常见的浏览器IE(6,8,9),chrome,firefox,safari等,还有国内的一些曾经靠恐吓用户来提高使用率的某浏览器(河蟹社会),这些浏览器对于Javascript的语言特性实现大致是相同的,但是对于DOM操作方式却大相径庭,所以我们通常需要自己对不同浏览器对于DOM的操作方式进行分而治之,或者我们往往是使用一些Javascript框架提供的兼容功能,当然也有我们的Microsoft AJAX Library

判断浏览器的类型和版本

浏览器兼容层的优势在于,我们可以使用同样的编码方式,让相同的代码在不同浏览器下的表现统一,因为在这个兼容层内部,分别实现了或者规避了一些浏览器的不同的实现,但是不同的浏览器的某些差异难以使用框架来保证,因此提供显式的判断浏览器的类型和版本是必不可少的

Sys.Browser

  • 通过windows.navigator.userAgent来判断
  • Sys.Brower.agent表示浏览器类型(可能的值InternetExplorer/FireFox/Safari/Opera)
  • Sys.Brower.hadDebuggerStatement:是否支持debugger命令
  • Sys.Brower.name:浏览器名称
  • Sys.Brower.version:浏览器版本
一个通过浏览器类型获得显示窗口的大小的示例

创建一个aspx页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="GetClientBoundsByBrowerType.aspx.cs" Inherits="Demo11_GetClientBoundsByBrowerType" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        
        <script language="javascript" type="text/javascript">
            document.write(window.navigator.userAgent);//打印浏览器信息
        </script>
        
        <hr />
        
        <script language="javascript" type="text/javascript">
            document.write("Has Debugger Statement:" + Sys.Browser.hasDebuggerStatement + "<hr/>");//是否支持debugger
            document.write("Name:" + Sys.Browser.name + "<hr/>");//浏览器名称
            document.write("Version:"+Sys.Browser.version);//浏览器版本
        </script>
        
        <script language="javascript" type="text/javascript">
            function getClientBounds() {
                var clientWidth;
                var clientHeight;
                switch (Sys.Browser.agent) {//判断浏览器类型
                    case Sys.Browser.InternetExplorer: //如果浏览器是InternetExplorer
                        clientWidth = document.compatMode == "CSS1Compat" ? document.documentElement.clientWidth : document.body.clientWidth;
                        clientHeight = document.compatMode == "CSS1Compat" ? document.documentElement.clientHeight : document.body.clientHeight;
                        break;
                    case Sys.Browser.Safari: //如果浏览器是Safari
                        clientWidth = window.innerWidth;
                        clientHeight = window.innerHeight;
                        break;
                    case Sys.Browser.Opera: //如果浏览器是Opera
                        clientWidth = Math.min(window.innerWidth, document.body.clientWidth);
                        clientHeight = Math.min(window.innerHeight, document.body.clientHeight);
                        break;
                    case Sys.Browser.Firefox: //如果浏览器是Firefox
                        clientWidth = Math.min(window.innerWidth, document.documentElement.clientWidth);
                        clientHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
                        break;
                }
                return { width: clientWidth, height: clientHeight };
            }
        </script>
        <hr />
        <div id="clientBounds"></div>
        <script language="javascript" type="text/javascript">
            window.onresize = function() {//当浏览器的大小改变的时候调用
            var bounds = getClientBounds();
                $get("clientBounds").innerHTML = String.format("Width:{0}<br/>Height:{1}",bounds.width,bounds.height);
            }
        </script>
    </form>
</body>
</html>

我这里使用的是IE8,chrome14.0和firefox6进行测试,得到的结果如下所示

IE8

chrome14.0

firefox6

这里我要提一下,其实Microsoft AJAX Library是没有直接的提供chrome的支持的,我这里使用它进行测试,完全是因为我这里只装了这三种浏览器,在chrome下,很多东西得出的结果是不正确的,只是让大家明白这里的不同,不要太多关注与它对chrome的支持

同样,这里我们也可以看到,在取到浏览器的尺寸的时候,各种浏览器的取得方法,是完全不相同的,这就是我们前面提到的对于DOM操作方式却大相径庭

针对DOM元素的兼容操作

  • Sys.UI.DomElement静态类中
  • $get=.getElementById=function(id,parent);//只是效果,并不等同
  • Sys.UI.DomElement.addCssClass=function(element,className);
  • Sys.UI.DomElement.removeCssClass=function(element.className);
  • Sys.UI.DomElement.containsCssClass=function(element,className);//判断元素下是否有这个className类
  • Sys.UI.DomElement.toggleCssClass=function(element,className);//如果元素有className,则去除,如果没有则添加
  • 可以自行添加缩写方法:eg:$addCss=Sys.UI.DomElement.addCssClass
  • Sys.UI.DomElement.getLocation=function(element)//返回Sys.UI.DomElement类型对象的位置
  • Sys.UI.DomElement.setLocation=funcation(element,x,y)
  • Sys.UI.DomElement.getBounds=funcation(element)//得到元素的大小和位置返回Sys.UI.Bounds
一个针对DOM元素的兼容操作的示例

创建一个名为DomElementOperations.aspx的页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DomElementOperations.aspx.cs" Inherits="Demo11_DomElementOperations" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        .red{color:Red;}
        .large{font-size:xx-large;}
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        
        <script language="javascript" type="text/javascript">
            //自行添加的缩写方法
            $addCss = Sys.UI.DomElement.addCssClass;
            $removeCss = Sys.UI.DomElement.removeCssClass;
            $containCss = Sys.UI.DomElement.containsCssClass;
            $toggleCss = Sys.UI.DomElement.toggleCssClass;
        </script>
        
        <input type="checkbox" id="inputElement" /><%--这里我们使用了两个相同的id--%>
        <div id="someContainer">
            <input type="text" id="inputElement" /><%--这里我们使用了两个相同的id,这个元素包裹在了一个DIV里--%>
        </div>
        <script language="javascript" type="text/javascript">
            document.write($get("inputElement").type + "<br/>");//这里将会打印checkbox,因为开始找到的是一个checkbox
            document.write($get("inputElement", $get("someContainer")).type + "<br/>"); //这里指定了将在id为someContainer的元素里找,所以是一个input
        </script>
        <hr />
        <div id="someText">
            Xiaoyaojian
        </div>
        <input type="button" value="Add Red" onclick="$addCss($get('someText'),'red')" /><%--添加一个red样式--%>
        <input type="button" value="Remove Red" onclick="$removeCss($get('someText'),'red')" /><%--去除一个red样式--%>
        <input type="button" value="Toggle Large" onclick="$toggleCss($get('someText'),'large')" /><%--如有有large这个元素,则去除,如果没有则添加--%>
        <input type="button" value="Container Large" onclick="alert($containCss($get('someText'),'large'))" /><%--判断元素上是否有large这个样式--%>
        
        <hr />
        
        <div id="anElement" style="background-color:Red; color:White; position:absolute; overflow:hidden;">
            Hello World
        </div>
        
        <script language="javascript" type="text/javascript">
            function setRandomLocation() {
                var left = Math.floor(Math.random() * 100);
                var top = Math.floor(Math.random() * 100);
                Sys.UI.DomElement.setLocation($get("anElement"), left, top);//设置位置,他相对左上角的位置是随机产生的
            }

            function setRandomSize() {
                $get("anElement").style.width = Math.floor(Math.random() * 100 + 50) + "px"; //设置元素的宽
                $get("anElement").style.height = Math.floor(Math.random() * 100 + 50) + "px";//设置元素的高
            }
            
            function showLocation() {
                var point = Sys.UI.DomElement.getLocation($get("anElement"));//显示元素相对浏览器左上角位置
                alert(String.format("x:{0},y:{1}",point.x,point.y));
            }

            function showBounds() {//显示元素的宽高(大小)和相对浏览器左上角的位置
                var point = Sys.UI.DomElement.getBounds($get("anElement"));
                alert(String.format("x:{0},y:{1},width:{2},height:{3}", point.x, point.y,point.width,point.height));
            }
        </script>
        
        <input type="button" value="Set Location" onclick="setRandomLocation()" />
        <input type="button" value="Set Size" onclick="setRandomSize()" />
        <input type="button" value="Show Location" onclick="showLocation()" />
        <input type="button" value="Show Bound" onclick="showBounds()" />
    </form>
</body>
</html>

在页面的代码注释里,我自认为已经写的足够的清楚,所以我在这里就不多做解释

针对DOM事件的兼容操作

出现的原因

  • 添加和删除event handler的方法不同
  • 获取Event对象的方法不同
  • Event对象的方法和属性不同
  • …等等
  • 因为种种原因,微软提供了一套“第三种形式的”DOM事件操作

提供的操作

  • 添加Event Handler:$addHandler(element,eventName,handler);//这里的事件名没有“on”
  • 添加Event Handler$addHandlers(element,events,owner);//events为一个存放Event Handler的字典,Owner为执行EventHandler的上下文对象
  • 去除Event Handler :$removeHandler(element,eventName,handler);
  • 去除所有的Event Handler: $clearHandlers(element);
  • Event Handler签名:on***(event);//event为一个Sys.UI.DomEvent类的对象
  • Sys.UI.DomEvent.preventDefault();//组织事件的默认行为
  • Sys.UI.DomEvent..stopPropagation();//阻断事件的向上传递
  • Sys.UI.DomEvent.altKey/ctrlKey/shiftKey;//触发事件时用户是否按着Alt/Ctrl/Shift键
  • Sys.UI.DomEvent.type:一个表示事件类型的字符串
  • Sys.UI.DomEvent.target:触发事件的DOM元素
  • Sys.UI.DomEvent.button:一个Sys.UI.MouseButton的枚举
  • Sys.UI.DomEvent.keyCode:一个表示当前按键的整数值,可以和Sys,UI,Key枚举的项找到对应关系
  • Sys.UI.DomEvent.clientX/clientY:鼠标在document可视范围内的位置(和滚动条状态无关)
  • Sys.UI.DomEvent.screenX/screenY:鼠标在屏幕中的位置
  • Sys.UI.DomEvent.offsetX/offsetY:鼠标在触发事件的对象中的相对位置
  • Sys.UI.DomEvent.rawEvent:浏览器原生事件对象
一个针对DOM事件的兼容操作的示例

创建一个asp页面,我们如果没有这个浏览器兼容层的情况下,我们如果为一个按钮在javascript中为一个按钮添加一个事件, 则需要如下代码来兼容不同的浏览器

<input type="button" value="Button" id="aButton" onclick="eventHandler(event)" />
        
        <script language="javascript" type="text/javascript">
            var button = document.getElementById("aButton");

            //只对IE有效果
            button.attachEvent("onclick", eventHandler);
            button.detachEvent("onclick", eventHandler);

            //只对firefox有效果
            button.addEventListener("onclick", eventHandler);
            button.removeEventListener("onclick", eventHandler);

            //兼容两种浏览器
            if (button.attachEvent) {
                button.attachEvent("onclick", eventHandler);
            }
            else {
                button.addEventListener("onclick", eventHandler);
            }
        </script>

而在我们有了这个浏览器兼容层的情况下,我们只需要做如下的操作

在页面中首先添加一个ScriptManager

<div style="width:300px; height:300px; background-color:Red" id="mouseEvent">
        </div>
        
        <script language="javascript" type="text/javascript">
            function onMouseDown(e) {
                $get("displayMouseEvent").innerHTML = String.format(
                    "altKey:{0}<br/>"+
                    "ctrlKey:{1}<br/>"+
                    "shiftKey:{2}<br/>"+
                    "clientX & Y:({3},{4})<br/>"+
                    "screenX & Y:({5},{6})<br/>"+
                    "offsetX & Y:({7},{8})<br/>" +
                    "button:{9}",
                    e.altKey,e.ctrlKey,e.shiftKey,//是否按着Alt/Ctrl/Shift这几个键
                    e.clientX,e.clientY,//可视范围内的位置
                    e.screenX,e.screenY,//相对于屏幕的位置
                    e.offsetX, e.offsetY,//相对于元素内部的位置
                    Sys.UI.MouseButton.toString(e.button));//表示按下的按键,左/右/中(按下滚轮)
            }

            $addHandler($get("mouseEvent"), "mousedown", onMouseDown); //为上面的div添加一个mousedown事件,触发这个事件,调用onMouseDown方法
        </script>
        
        <div id="displayMouseEvent"></div><%--要显示信息的DIV—%>

这时,我们可以在红块内点击鼠标的左右中键,并同时按下Alt/Ctrl/Shift键盘,就可以清晰的反映到下面的DIV的信息里

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏DannyHoo的专栏

iOS中在系统相册中创建自己App的自定义相册

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

1001
来自专栏MasiMaro 的技术博文

菜单的使用

2)弹出式菜单:一般在顶级菜单上都有很多菜单项,单击这些菜单项时会弹出一个下拉式的菜单项,我们点击的这个菜单称为弹出式菜单

994
来自专栏IT派

Javascript 将 HTML 页面生成 PDF 并下载

最近碰到个需求,需要把当前页面生成 pdf,并下载。弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :)

1001
来自专栏守候书阁

[边学边练]用简单实例学习React

学习之路不可停止,最近在玩 React。也动手尝试写了一个实例。借此整理总结下初步学习 React 的一些基础知识。因为这几天比较忙,没那么多时间,所以实例和文...

1256
来自专栏ASP.NET MVC5 后台权限管理系统

FullCalendar 日历插件中文说明文档

FullCalendar提供了丰富的属性设置和方法调用,开发者可以根据FullCalendar提供的API快速完成一个日历日程的开发,本文将FullCalend...

5728
来自专栏向治洪

React Native控件只TextInput

TextInput是一个允许用户在应用中通过键盘输入文本的基本组件。本组件的属性提供了多种特性的配置,譬如自动完成、自动大小写、占位文字,以及多种不同的键盘类型...

2678
来自专栏大壮

iOS 动画(理论篇)

1465
来自专栏Web项目聚集地

Javascript将HTML转成PDF并下载「支持多页」

由于html2canvas只能将它能处理的生成canvas image,因此渲染出来的结果并不是100%与原来一致。但它不需要服务器参与,整个图片都由客户端浏览...

1372
来自专栏程序员宝库

分享前端开发常用代码片段

如果你的网页中需要使用大量初始不可见的(例如,悬停的)图像,那么可以预加载这些图像。

1185
来自专栏程序员宝库

Javascript 将 HTML 页面生成 PDF 并下载

最近碰到个需求,需要把当前页面生成 pdf,并下载。弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :)

1043

扫码关注云+社区