`
alvinqq
  • 浏览: 181698 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

总结浏览器

阅读更多
其实我在浏览器这方面懂的也不多,只是平时在解决问题的时候积累了一点点的经验,浏览器兼容问题一般表现在JS代码上,CSS样式上,对于java代码来 说没有这个概念(本人认为),所以只要解决JS能够在多种浏览器上都能正常运行就OK了,但并不是所有的浏览器都能找到共性的JS代码(属性,方法),所 以又很多问题就得靠我们自己去想其他办法来解决,这就要依靠下面这段代码(浏览器的判断)
Page.jsp
//浏览器的判断
brower = function() {
    var ua = navigator.userAgent.toLowerCase();
    var os = new Object();
    os.isFirefox = ua.indexOf ('firefox') != -1;
    os.isOpera = ua.indexOf ('opera') != -1;
    os.isChrome = ua.indexOf ('chrome') != -1;
    os.isIE = !os.isOpera  &&  ua.indexOf ('msie') != -1;
    os.isIE7 = os.isIE  &&  ua.indexOf ('7.0') != -1;
    os.isIE8 = os.isIE  &&  ua.indexOf ('trident/4.0') != -1;
    return os;
}
JS调用方法:brower().isIE7
有了这个东西,我们遇到的一些问题就能很好的解决,如果在浏览器这方面经验不足,我们就可以不必去知道哪些属性或方法是每个浏览器都支持的,只要我们很好的利用这个判断,然后再结合自己的想法去完成那些兼容问题。
有很多东西都需要自己去慢慢琢磨,到网上多查点资料,像上次那个插件的问题,是判断浏览器中是否安装了Flash插件,我到网上查了一下,OK,但是放到程序中又有点问题
源码:
IE中
var swf=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
(swf)?document.write(“已经安装了插件”):document.write(“没有安装“);
后来发现这个方法只能在浏览器中已经安装插件的情况下才能正确的判断
如果没有浏览器还没有安装插件,运行代码会报一个“Automation服务器不能创建对象“的错误,我开始想了很久是不是浏览器的设置的安全级 别原因,后来证实不是,后来我就想,既然没有安装插件用这个方法报错,就等于运行这段代码程序就会抛出异常,我把这个异常捕获不就能解决这个问题了吗?然 后我就对它进行了异常的捕获,代码如下:
Uploadfile.jsp
//IE中判断是否安装插件
var swf;
function IE_Flash()
{
    try
    {
        var swf=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
        alert("已安装插件");
    }
    catch(e)
    {
        alert("没有安装插件");
    }
}
//FireFox,Chrome中判断是否安装插件
function FF_or_Chrome_Flash()
{
    var swf=navigator.plugins["Shockwave Flash"];
    (swf)?alert("已安装插件"):alert("没有安装插件");
}
火狐中的判断不会出现这样的问题,然后结合上面的浏览器判断就能在程序中跑的很欢了。
不过有些浏览器兼容问题也是无法解决的,像谷歌就不支持图片的预览,这个我真的拿它没辙。解决方案:只能修改页面风格 ,我看了其他很多支持图片上传的网站,像最常见的QQ相册,它在谷歌中也没有支持对图片的预览,而且在谷歌中的上传页面风格跟其他浏览器中的风格截然不同,还有一些支持相册功能的邮箱也一样,他们都是通过改变页面风格来规避这个问题。
根据id去取得文本对象的值是所有浏览器都支持的,但是必须严格要求id的大小写,在IE中id不区分大小写,但是谷歌中是区分的。所以有些时候我们看到根据id去取值的时候,明明命名是相同的,就是取不到值,这时候就要注意命名的规范了(大小写)

上传控件样式:
在谷歌中,上传控件的样式很怪,完全异同与IE和FireFox,而这种风格又不是CSS能解决的,这时我们只能通过其他的方法来解决,具体的解决方法有两种:
一:通过滤镜的效果,将原来的上传控件设置成透明,然后另外在自己做一个文本框和一个按钮,当点击这个按钮时,实际上是点击上传控件。
像APP中,上传控件要做的那么漂亮,在多浏览器中风格要统一,就必须使用滤镜,但是在FireFox中的滤镜的设置根IE和Chrome又不同,这个我后来到网上查了一下,解决了,
源码如下:
Register.jsp
CSS:
/* FireFox */
.FF_file
{
position:absolute;
-moz-opacity:.0;
width:0px;
height:20px;
}

/* IE,Chrome */
.IE_file
{
position:absolute;
filter:alpha(opacity=0);
width:0px;
height:20px;
}

-moz-opacity:.0; filter:alpha(opacity=0);
通过改变其中的数值大小(0~100之间的整数)便能够控制透明度,这有利于最开始的调试
Register.jsp
Html:
<input type="text" id="filepath" readonly='true' style="height: 26px;border: #cdcdcd 1px solid">

<input type="button" id="upload" value="浏 览" onmouseover="selectFilterStyle(this,fileRoad,event);" class="btn5" title="<s:text name='icon_tip'/>">

<input id="fileRoad" type="file"  onchange="changeImg(this)" name="icon" autocomplete="off" contentEditable="false" hidefocus>
Register.jsp
JS:
/**
*在页面加载的时候就将上传控件的滤镜设置好
*/
Window.onload=function()
{
var fileRoad=document.getElementById("fileRoad");
if(brower().isFirefox){
fileRoad.className='FF_file';
}
else{
fileRoad.className='IE_file';
}
var upload=document.getElementById("upload");
fileRoad.onmouseout=function(){
upload.className='btn5';
}
upload.onmouseout=function(){
upload.className='btn5';
}
}

/**
*当鼠标移动到我们做的按钮上时,上传控件变会浮动在按钮上,并根据光标的移动而时刻改变*坐标,但范围限制在按钮上,光标从按钮上移开时上传控件的坐标就不会变动了。
*/
function selectFilterStyle(ower,obj,evt)
{
obj.onmouseover=function(){
ower.className='btn6';
}
if(brower().isFirefox)
{
obj.className='FF_file';
obj.style.left=evt.pageX-210;
obj.style.top=evt.pageY-15;
}
else
{
obj.className="IE_file";
obj.style.left=event.clientX-70;
obj.style.top=event.clientY-15;
}
}
注:evt和event将在后面进行描述
第二种方法:
跟第一种方法有相似点,但不会采用滤镜,同样是将长传控件影藏,然后自己在做一个文本框和一个按钮,当点击按钮时便触发上传控件的单击事件。但是这个方法只能很好的解决掉谷歌中上传控件的样式问题,这个对于页面要求不是特别一致的时候比较实用,因为FireFox中的event只能在事件发生的现场使用。
源码如下:
Page.js
/**
*将原来的上传控件设置成不可见,但是不能用display:none来控制,虽然能触发它,但
*文件的选择窗口也会被影藏,所以只能设置上传控件的大小,width和height,size
*@param fileId:是长传控件的id
*@param spanId:是我们<span/>的id
*@param borderColor:是设置上传控件的边框样式
*@param size:是设置上传控件的文本框长度
*/
function setFileStyle(fileId,spanId,borderColor,size)
{
   if(brower().isChrome)
   {
   document.getElementById(fileId).style.width="0px";
   document.getElementById(fileId).style.height="0px";
   document.getElementById(fileId).style.border="0px white solid";
   document.getElementById(fileId).size=0;
   document.getElementById(spanId).innerHTML="<input id='filetext' style='border:1px "+borderColor+" solid;width=350px;margin-left:0px;padding-left:0px' size='"+size+"' readonly='readonly'/><input id='b' type='button' value=' 浏览 ' style='border:1px "+borderColor+" solid;cursor:hand'/>";
    filetext.onclick=function()
    {
   this.focus();
document.getElementById(fileId).click();
    }
    b.onclick=function()
    {
   this.focus();
document.getElementById(fileId).click();
    }
}
}
调用方法:
在页面加载的时候就调用:
Window.onload=function()
{
setFileStyle('vasLogoID','imgfile','#666666',16);
}
第一个参数:是长传控件的id
第二个参数:是我们<span/>的id
第三个参数:是设置上传控件的边框样式
第四个参数:是设置上传控件的文本框长度
expressShopAdd.jsp
Html:
<span id='imgfile'></span>
<INPUT type="file" class=input2 style="WIDTH: 200px" contentEditable="false" maxLength=16 name="myFile" id="vasLogoID" onchange="if(brower().isChrome)document.getElementById('filetext').value=this.value;">
这种方法适合DMS(对风格要求不是特别高,只是在火狐中会有一点点区别,但不影响大局)
字段换行:
在IE和Chrome中,表格的宽度已经设置好之后再加上一个样式控制(style="WORD-BREAK: break-all; WORD-WRAP: break-word;")就不会变了,其实这个方法在Firefox中也有作用,但是在测试的时候,我们往往保存的字符是没有规律的,有可能就是一长串乱七八糟的字母或数字,这个时候,在FireFox它就不会给你自动换行了,上面样式控制的意思是,当字符串长度已经超过表格列宽,而且字符串是一些汉字或是一些完整的英文单词的时候就
会自动换行。但是在IE和Chrome没有加这个表格样式也照样给我们换行,FireFox就不给面子了,所以我们就得强制去换行,强制换行的一个手段就是循环去截取,这个就用利用到Struts2.0中的(<s:bean name="org.apache.struts2.util.Counter">)标签了,(Struts2.0比1.2还是好使)
源码如下:
leaveMessageList.jsp
<s:if test="message.length()>=20">
<s:bean name="org.apache.struts2.util.Counter">
<s:param name="first" value="1"></s:param>
<s:param name="last" value="message.length()%20==0?message.length()/20:(message.length()/20)+1"></s:param>
<s:iterator>
<s:propertyvalue="message.substring((current-2)*20,(current-1)*20)"/>
<br>
<s:if test="message.length()%20!=0 && current==(message.length()%20==0?message.length()/20:(message.length()/20)+1)">
<s:property value="message.substring(message.length()-message.length()%20,message.length())"/>
</s:if>
</s:iterator>
</s:bean>
</s:if>
<s:else>
<s:property value="message"/>
</s:else>
首先通过if,else判断,这个字段值的长度大于设定的数值就换行
通过引入
<s:bean name="org.apache.struts2.util.Counter">
<s:param name="first" value="1"></s:param>
<s:param name="last" value="10"></s:param>
<s:iterator>
Current:<s:property value="current"/>
</s:iterator>
这个标签相当于java中的for循环
其中:first-是初始值 last-是最大值 current-是代表每次循环后自增1的值,可以通过标签输出:
Current:1
Current:2
Current:3
Current:4
Current:5
Current:6
Current:7
Current:8
Current:9
Current:10
文本框的统一过滤:
我们有时要控制文本框只能输入部分字符,但是又没有公共的方法来控制,像onpropertychange在IE7中是支持的最好的,在FireFox中是不支持的,
所以我们就得考虑其他的方法 通过onkeyup,onkeydown来控制其他浏览器的支持就比较好
Page.js:
//只能输数字和字母
function filterNumber_Letter(obj,b)
{
if(brower().isIE7 && b=='IE7')
{
if(/[^a-zA-Z\d]/ig.test(obj.value))obj.value=obj.value.replace(/[^a-zA-Z\d]/ig,'');
}
else if(brower().isIE  && b=='FF')
{
if(/[^a-zA-Z\d]/ig.test(obj.value))obj.value=obj.value.replace(/[^a-zA-Z\d]/ig,'');
}
else if(brower().isFirefox  && b=='FF')
{
if(/[^a-zA-Z\d]/ig.test(obj.value))obj.value=obj.value.replace(/[^a-zA-Z\d]/ig,'');
}
else if(brower().isChrome  && b=='FF')
{
if(/[^a-zA-Z\d]/ig.test(obj.value))obj.value=obj.value.replace(/[^a-zA-Z\d]/ig,'');
}
else if(brower().isIE8  && b=='FF')
{
if(/[^a-zA-Z\d]/ig.test(obj.value))obj.value=obj.value.replace(/[^a-zA-Z\d]/ig,'');
}
}
然后我们在页面上文本框调用的时候如下:
onpropertychange="filterNumber_Letter_Rail(this,'IE7');"
onkeyup="filterNumber_Letter_Rail(this,'FF');"
onkeydown="filterNumber_Letter_Rail(this,'FF');"
加上这个之后,我们就能很好的控制字符的输入了
谷歌浏览器记住密码:
当我们登录系统后,浏览器会提示“保存密码”,如果点击“保存密码”,这时,进入操作页面的时候,有些添加页面如果有需要输入密码的地方,浏览器就会自动帮我们初始化我们的登录名和密码,在Firefox中通过页面加载的时候清空文本框就能解决掉,但是谷歌不吃这套,我们就得另外想办法了:
源码如下:
Page.jsp

/**
*设置参数到Cookie中
*@param name:谷歌记住的用户名的文本款的id
*@param pass:谷歌记住的密码的文本框的id
*/
function clearCookie(name,pass)
{
setCookie("name",name);
setCookie("pass",pass);
if(brower().isChrome)
{
window.setTimeout("clearSe()",100);
}
}
function clearSe()
{
var name=getCookie("name");
var pass=getCookie("pass");
document.getElementById(name).focus();
document.getElementById(name).blur();
document.getElementById(pass).focus();
document.getElementById(pass).blur();
document.getElementById(name).value="";
document.getElementById(pass).value="";
deleteCookie("name");
deleteCookie("pass");
}
通过这个方法,当进入页面后,定时器会在0.1秒后执行清空操作
注:Cookie的操作方法见Page.jsp

上面是我解决的一些比较典型的问题,有很多问题并不是靠一些公用的属性就能解决的。
浏览器的判断这个方法很有用,能够很好的帮助我们判断根据不同的浏览器做不同的操作

不过有些浏览器兼容问题也是无法解决的,像谷歌就不支持图片的预览,这个我真的拿它没辙。解决方案:只能修改页面风格
IE中id
下面是我在网上查的一些兼容问题,并结合自己平时用到的一些比较有用的,常用的:
以下以 IE 代替 Internet Explorer,以 ff 代替Firefox。
1. childNodes在ff中和ie的区别。
ff中的node(nodeType = 1)都是用textNode(nodeType = 3)分开的,而ie/op不是这样的。
content
在ff下,box1的childNodes为3个,ie下为1个。
2. 设置某个node对象的style class名称。
ie中要设置某个node的class用”className”作为attr来set或者get。
ff等其它的浏览器用”class”作为attr来set或者get。
代码:
if(typeof node1.getAttribute(”className”) == “string”) {
….
}
3.事件对象。
window.event只能在IE下运行,而不能在Firefox下运行,这是因为Firefox的event只能在事件发生的现场使用. Firefox必须从源处加入event作参数传递。

4.鼠标坐标差异
IE下,even对象有x,y属性,但是没有pageX,pageY属性;Firefox下,even对象有pageX,pageY属性,但是没有x,y属性.
5.pixelLeft和pixelTop差异
IE有,FireFox没有
document.form.item 问题
现有问题:
现有代码中存在许多 document.formName.item("itemName") 这样的语句,不能在 ff 下运行
解决方法:
改用 document.formName.elements["elementName"]
集合类对象问题
现有问题:
现有代码中许多集合类对象取用时使用 (),IE 能接受,ff 不能。
解决方法:
改用 [] 作为下标运算。如:document.forms("formName") 改为 document.forms["formName"]。
又如:document.getElementsByName("inputName")(1) 改为 document.getElementsByName("inputName")[1]

HTML 对象的 id 作为对象名的问题
在 IE 中,HTML 对象的 ID 可以作为 document 的下属对象变量名直接使用。在 ff 中不能。
解决方法:
用 getElementById("idName") 代替 idName 作为对象变量使用。
用idName字符串取得对象的问题
变量名与某 HTML 对象 id 相同的问题
现有问题:
在 ff 中,因为对象 id 不作为 HTML 对象的名称,所以可以使用与 HTML 对象 id 相同的变量名,IE 中不能。
解决方法:
在声明变量时,一律加上 var ,以避免歧义,这样在 IE 中亦可正常运行。
此外,最好不要取与 HTML 对象 id 相同的变量名,以减少错误。
event.x 与 event.y 问题
现有问题:
在IE 中,event 对象有 x, y 属性,ff中没有。
解决方法:
在ff中,与event.x 等效的是 event.pageX。但event.pageX IE中没有。
故采用 event.clientX 代替 event.x。在IE 中也有这个变量。
event.clientX 与 event.pageX 有微妙的差别(当整个页面有滚动条的时候),不过大多数时候是等效的。
如果要完全一样,可以稍麻烦些:
mX = event.x ? event.x : event.pageX;
然后用 mX 代替 event.x
父结点的问题
在ff中没有 parentElement parement.children 而用 parentNode parentNode.childNodes
childNodes的下标的含义在IE和ff中不同,ff使用DOM规范,childNodes中会插入空白文本节点。
一般可以通过node.getElementsByTagName()来回避这个问题。当html中节点缺失时,IE和ff对parentNode的解释不同,例如
ff中input.parentNode的值为form, 而IE中input.parentNode的值为空节点
ff中节点没有removeNode方法,必须使用如下方法 node.parentNode.removeChild(node)
body 对象
ff的body在body标签没有被浏览器完全读入之前就存在,而IE则必须在body完全被读入之后才存在
1, FF下给 div 设置 padding 后会导致 width 和 height 增加, 但IE不会.(可用!important解决)
2, 关于手形光标. cursor: pointer. 而hand 只适用于 IE.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics