1. 在chrome浏览器出现Uncaught SyntaxError: Unexpected token u
在chrome浏览器出现 Uncaught SyntaxError: Unexpected token u 页面一片空白 显示不了,在Firefox正常
问题原因: 由于使用了localStorage ,会造成废弃或者未定义的数据,就是udefined,当使用Json.parse()解析值为udefined的Json数据时 chrome 就会抛出错误,而FireFox会返回正确的字符窜,
解决方法,使用LocalStorage.removeItem()把拥有undefined的数据清掉; 问题链接
2. new Date()对象的兼容性问题
chrome浏览器支持 “1990-08-10 15:20:10”的格式,其他浏览器不支持,统一支持的是new Date(2015,10,20,15,12),但是chrome得出的是正确的时间,而firefox与IE 的出的时间比正常的时间少了8个小时
chrom:
fireFox:
firefox获取时间或许是时区的问题,但是可以使用valueOf()取它们的毫秒数是一样的。所以还是老实的getDate,getHours、getMinute吧
jq.formatCommonTime = function(millisec, isSample) {
var time = new Date();
time.setTime(millisec || 0); //设置需要格式化的时间
if (!!isSample) {
return (time.getMonth() + 1) + '月' + time.getDate() + '日';
}else{
return time.getFullYear() + '年' + (time.getMonth() + 1) + '月' + time.getDate() + '日 ' + time.getHours() + ':' + ((time.getMinutes() < 10) ? "0" : "") + time.getMinutes();
}
}
3、IE浏览器控制台出现 Exception in window.onload: Error: An error has ocurredJSPlugin.3005
原因是IE浏览器自身更新问题 只要下载补丁更新就好了补丁下载链接
4 、需要判断出IE8浏览器
<!--[if lt IE 9]>
.series em{
text-align: right!important;
}
<![endif]-->
//如果是因为其他原因使用不了,比如sass编译会出错,可以使用Jquery方法判断
//判断是否是IE8及以下
var ie8 = $.support.leadingWhitespace;
if(!ie8){
$('em').addClass('ie8');
}
5、Jquery 使用scroll()函数在IE8及以下出现问题
原因是监听的是document、或者body,只有改成window就可以了。
//滚动显示侧边栏
$(window).scroll(function(){
var scrollTop = $(document).scrollTop();
if(scrollTop >= 630){
$('.m-menu').show();
}else{
$('.m-menu').hide();
}
});
6、在服务器上安装 npm install的时候出现
npm WARN package.json methods@0.0.1No license field.
npm WARN package.json methods@0.0.1No repository field.
npm WARN package.json methods@0.0.1No readme data.
只要在package.json 里面加上
"repository":{"type":"git","url":"git://github.com/username/repository.git"}
or
{"name":"my-application","version":"0.0.1","private":true}
就可以了
7、移动端视频播放支持
移动端不支持视频自动播放,所以只好采用poster的方式,如果采用遮盖一层封面的话,则需要点击两次才可以。
还有在安卓手机的微信,当切换page时(fullpage.js会出现),播放器会浮起,所以在离开当前页面时把视频remove掉,页面加载时重新生成视频。
但是好像iphone手机是支持自动播放的,但是偶尔又不行了。在安卓端如果把controls加上、autoplay去掉,基本可以播放,但是video标签需要换一种格式来写,也可能有些手机对视频的格式有要求:
if(b._$IS['android']){
videoFlag = '<video width="100%" controls="controls" preload="auto"><source src="' + _vLink + '"><p>你的手机不支持video播放器</p></video>';
}else{
videoFlag = '<video width="100%" preload="auto" src="' + _vLink + '" autoplay="autoplay"></video>';
}
或
var videoFlag = '<video width="100%" controls="controls" preload="auto"><source src="' + _vLink + '">
<source src="https://broken-links.com/tests/media/BigBuck.webm" type="video/webm">
<source src="https://broken-links.com/tests/media/BigBuck.theora.ogv" type="video/ogg">
<p>你的手机不支持video播放器</p>
</video>';
8、隐藏元素的滚动条
#element::-webkit-scrollbar {display: none;}
//If you want all scrollbars hidden, use
::-webkit-scrollbar {display: none;}
// I'm not sure about restoring - this did work, but there might be a right way to do it:
::-webkit-scrollbar {display: block;}
overflow属性设置的值为visible、scroll、hidden、auto
visible 默认值。使用该值时,无论设置的"width"和"height"的值是多少,其中的内容无论是否超出范围都将被强制显示。
hidden 效果与visible相反。任何超出"width"和"height"的内容都会不可见。
scroll 无论内容是否超越范围,都将显示滚动条。
auto 当内容超出范围时,显示滚动条,否则不显示。
所以当div里面的内容高度不固定时,如果超出高度就出现滚动条,如果高度不够那就不出现滚动条,这个时候应该使用auto
9、移动端页面上出现没能适配整个屏幕
在移动端的页面中,在chrome模拟调试时发现是完全可以适配屏幕的,但是到了其他浏览器以及微信上出现了页面可以左右滚动的问题,检查html,body,都没有发现有元素溢出,一层层排查进来,发现是内容区域的确有div溢出了,原因是宽度定为了屏幕宽度90%,需要居中,使用left:50%,margin-left:-25%;类似的方法,可能有些浏览器的渲染方式不一样,才会出现这种问题
10、IE8不支持innerHTML的赋值,报未知运行错误。
在ie8中,可以看淡dom对象是有innerHTML属性的,并且能获取到innerHTML的值,但是呢,却不能给innerHTML赋值, 比如说 domObj.innerHTML = "1"都不行。一番查找之后,发现innerHTML的确有这个问题,但是也只是局限于在tbody中不能用innerHTML插入tr或者是不能往inline元素插入block元素,但我的情况并不属于这两种。是网div里面插入div,实在搞不清楚原因,所以也只能另寻办法了。就是使用createElement()生成节点,然后再appendChild()的方式解决ie8下的问题
if(!eu._$ltIE10()){
this.__serviceList.innerHTML = str;
}else{
e._$clearChildren(this.__serviceList);
var _nodeList = e._$html2node(str);
this.__serviceList.appendChild(_nodeList);
}
//html2node 方法的实现方式:
_e._$html2node = function(_html){
var _div = document.createElement('div');
_div.innerHTML = _html;
var _list = _e._$getChildren(_div);
return _list.length>1?_div:_list[0];
};
按照html2node的实现方式,其实ie8是支持innerHTML的,唯一可能不同的就是this.__serviceList 与_div;
11、ios点击返回按钮取缓存数据时候,如果接口返回的数据的key一样,ios会以为这些数据都是同一份。
做的一个webView页面时候,使用相同的key(原来只是wish_card,并没有index),不同的课程id去请求数据,然后以相同的key返回数据,
页面刚加载的时候,数据是正确的,但是随便点击一个课程卡片跳转到详情页,然后再返回的时候页面却使用了同一份数据。
//初始化课程卡片
$('.course-box').each(function(index, item) {
var courseIds = $(item).attr('data-courseIds');
if(!!courseIds){
getCourseData(item, courseIds, index);
}
});
function getCourseData (node, courseIds, index) {
var cardInfo = '[{"key":"wish_card' + index + '","secKillFlag":0,"infos":' + courseIds + '}]';
var _cardInfo = {jsonStr:cardInfo};
var url ="http://study.163.com/promote2015Q3/getCourseInfos.htm";
jq.post(url, _cardInfo, cbGetCourseData, 'json');
function cbGetCourseData (data) {
var options = {
showCart: false,
showCount: true,
showDesc: false,
showLector: true,
type: 2,
gaPrefix:"",
data: data['wish_card' + index]
};
$(node).courseCard(options);
}
}
返回的数据类型:{"wish_card4":[{"productId":1278001,"productName":"漫画统计å
初步判断是ios读取缓存的问题,因为用fiddler抓包,返回的时候并没有重新发出请求。那么因为是取的同一份数据,那么应该会是因为ios判断这些数据都是同一份,
js代码里面唯一能让ios产生混淆的应该是key的问题了,于是给key加了index,然后就解决了
13、firefox 与chrome 获取html 文档的方式不一样
当获取页面的窗口进行页面滚动时,chrome、ie、safari使用的是document.body,而firefox取的是document.documentElement,所以可以选择使用这样的方式解决兼容性问题
var docBody = document.body || document.documentElement;(可以取window 比如$(window))
//我的奖励明细
$('#j-myDetail').click(function(){
//fireFox 中document.body.scrollTop 永远等于0、
//chrome中document.documentElement.scrollTop 永远为0,
//但是因为页面刚加载完scrollTop都是0 所以无法使用这个来判断,所以暂时还是判断UA
var docBody = (ua.indexOf('firefox') != -1) ? document.documentElement : document.body;
$(docBody).animate({scrollTop: $('.l-m-sharelist').offset().top},200,function(){
$('#j-openList').addClass('open');
$('#j-dataList').slideDown(10,function(){}).addClass('hasOpen');
});
});
14、服务器端记录的cookie需要带上domain、path才能清掉
//如果服务器端记录cookie,那么一般都是记在根域名、根目录下、比如study记的cookie
domain: .study.163.com path: /
//那么在专题页面清除cookie的时候,是path不一样,专题的path /topics/sales,所以是删除不了的
$.removeCookie('inviteFromSpringsales');
//改成
$.removeCookie('inviteFromSpringsales',{path:'/',domain:'study.163.com'});
15、javascript中的深拷贝和浅拷贝
其实深拷贝与浅拷贝的最终得到的结果都一样的,只是浅拷贝出来的新对象与元对象指向同一个内存地址,改变任何一个都会影响到另一个对象。而深拷贝则是把数据拷贝出来放到新的内存地址,两个对象的数据不会影响
//浅拷贝:
var obj1 = { a:1, b:{ c:2 }};
var obj2 = obj1;
console.log(obj2); //{ a:1, b:{ c:2 }};
obj2.b.c = 3;
console.log(obj1) //{ a:1, b:{ c:3 }};
//obj1的值也改变了
//深拷贝:
var obj1 ={a:1,b:{c:2}};
function deepCopy(_originObj){
if(_originObj==null)return null;
if(typeof _originObj !== "object"){
return _originObj;
}
var _clone = {};
if(_originObj.constructor == Array){
_clone = [];
}
for(var i in _originObj){
_clone[i] = arguments.callee(_originObj[i]);
}
return _clone;
}
var obj2 = deepCopy(obj1);
console.log(obj2); //{a:1,b:{c:2}}
obj2.b.c = 3;
console.log(obj1); //{a:1,b:{c:2}}
//obj1并不会被改变
16、使用Object.prototype.toString.call(_data).toLowerCase()=='[object '+_type+']'; 判断一个变量的数据类型
(1) 在toString方法被调用时,会执行下面的操作步骤:
(2) 如果this的值为undefined,则返回"[object Undefined]".
(3) 如果this的值为null,则返回"[object Null]".
(4) 让O成为调用ToObject(this)的结果.
(5) 让class成为O的内部属性[[Class]]的值.
(6) 返回三个字符串"[object ", class, 以及 "]"连接后的新字符串.
var _isTypeOf = function(_data,_type){
try{
_type = _type.toLowerCase();
if (_data===null) return _type=='null';
if (_data===undefined) return _type=='undefined';
return Object.prototype.toString.call(_data).toLowerCase()=='[object '+_type+']';
}catch(e){
return !1;
}
};
16、文件上传获取判断文件的尺寸大小
判断文件的width and height 、_URL方法只支持现代浏览器,移动端未测试过,使用的时候会出现一个问题,img.onload方法并不会阻塞js的执行,所以需要使用图片大小判断的后续代码,只能放到onload方法中执行。
方法一: 只需要获取input:file 框就可以
try{
var _URL = window.URL || window.webkitURL,
img = new Image();
img.onload = function(){
console.log(this.width + '*' + this.height);
if(this.width < 800 || this.height < 300){
that.errorTips('图片大小不能小于800*300哦');
uploadPro.__resetFile();
return false;
}
that.filename = _fileName;
return true;
}
img.src = _URL.createObjectURL(this.__realUpload.files[0]);
}catch(e){
console.log('can not get image width and height');
}
方法二: 需要获得图片的url
var img = new Image();
img.onload = function(){
console.log(this.width + '*' + this.height);
if(this.width < 600 || this.height < 300){
mUploadErrorTips('图片大小不能小于600*300哦');
$('#j-selectFile').css({'display':'block'});
$('.filename').html('');
$('#j-reselectBox').css({'display':'none'});
return false;
}else{
saveData();
}
}
img.src = _data.originPhotoUrl;
17、一些奇奇怪怪的bug
(1) 一些情况下对非可点击元素监听click事件,ios下不会触发,css增加cursor:pointer就搞定了。当然想要干脆静止点击就是not-allowed。
(2) qq浏览,uc浏览以及ios的浏览器,滚动时不会触发scroll事件,但会触发touchmove。当停止滚动后会出发scroll。
(3) -webkit-tap-highlight-color可以取消点击高亮。
(4) android4.4以下版本,设置圆角属性需要在直接元素上,向父元素设置圆角并且指定overflow:hidden是不会生效的。
18、关于微信屏幕支付宝支付的解决方案
因为考拉那边在微信中可以使用微信支付,经过抓包分析发现,微信屏蔽是根据当前页面的链接来的,当webView页面加载完毕之后,
(1) 微信发现当前页面的链接如果是阿里的链接,那么就会跳转到另外一个页面。
(2) 解决方案是在自己的域名下的文件嵌套一个iframe,然后使用iframe加载支付宝的页面就ok了,
(3) 因为微信app里面监听不到iframe加载完毕的事件,也就无法判断iframe加载的页面。
主要逻辑:
在支付页面,前端会把支付物品信息通过form表单通过iframe提交给后端,然后后端把物品的信息编码成一个链接然后redirect到阿里的支付页面,然后在iframe中这个链接会跳转到阿里的支付页面,正常情况下这样就结束了。
但是为了解决按返回按钮后的复杂操作,所以决定新开一个页面进行提交,所以并不需要后端直接跳转,而是先跳转到一个新的页面并把支付链接回填回来。
然后前端拿到支付链接之后,把链接赋值到iframe中,那么iframe就会跳转到支付宝的支付页面,就可以了。
但是前端给siframe的src赋值时,出现了一个refused display page 'http://study.163.com/xxx', because x-frame-sameorigin 的错误,页面显示不出来,
原因是前端不能手动给iframe设置与父页面相同域名的链接?,所以只好叫后端跳转了。
payOrder.ftl 提交物品信息给后端
<form action="/pay/orderRedirectPage.htm" name="payForm" id="payForm">
<input type="hidden" name="orderUrl" id="toPayUrl"/>
</form>
后端跳转到 alipayOrder.ftl 并回填支付链接
<body style="min-height:520px;margin:0;padding:0;background-color:#f5f5f9;">
<!-- 顶部导航栏 -->
<div class="g-content" style="min-height:520px;">
<iframe src="" style="min-height:520px;" id="j-alipay" name="alipay" src="" style="border:none;" width="100%" height="100%"></iframe>
<form action="/pay/mobileAlipay.htm" name="payForm" id="payForm" target="alipay">
<input type="hidden" name="orderUrl" id="toPayUrl"/>
<input type="hidden" name="redirectToAlipay" value="true" id="toPayUrl"/>
</form>
</div>
<!-- @NOPARSE -->
<script>
<#if orderUrl?exists>window.orderUrl = "${orderUrl?html}";</#if>
if(!!window.orderUrl){
document.getElementById('toPayUrl').value = window.orderUrl;
console.log(window.orderUrl);
document.forms[0].submit();
}
</script>
<!-- /@NOPARSE -->
alipayOrder.ftl 获取到支付链接再构造一个表单通过iframe提交给后端,然后后端直接进行跳转,那么iframe里面就可以跳转到支付宝支付页面了。
19、在ios微信浏览器中出现fixed定位低z-index元素覆盖在absolute定位高z-index元素上面
在微信浏览器中,首先要弹出一个框,点击这个弹框的一个按钮之后,如果保存成功,就会关闭当前弹框,然后再弹出另一个框,然后就出现了cover层覆盖在了弹框上面
结构以及样式如下
蒙层样式
div.m-com-mask {
z-index: 1000;
background-color: #3b3b3b;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
opacity: 0.75;
filter: alpha(opacity=75);
}
弹窗样式
div.m-winmark {
position: absolute;
z-index: 4001;
top: 886.5px;
left: 47px;
border: 1px solid #BABECB;
background: #ffffff;
color: #444;
box-shadow: 0px 3px 14px #aaa;
-webkit-box-shadow: 0px 3px 14px #aaa;
}
html结构
<div class="auto-1464943864173 m-com-mask"> </div>
<div class="auto-1464943864174 m-basewin" style="top: 886.5px; left: 47px;">
<div class="zbar" id="auto-id-1464943864232">
<div class="icon ic4"></div>
<div class="cnt cntnom">关注成功!</div>
</div>
<span class="zcls" title="关闭" id="auto-id-1464943864231">×</span>
</div>
其实简单的说就是两个兄弟元素A、B,A是fixed定位但是层级z-index低,B是absolute定位但是层级高,按正常情况B是覆盖在A前面的,但是在微信浏览器情况确实A覆盖在B的前面,但是更奇葩的是,就算A覆盖在B的前面了,还是可以点到B的。结果就是以下
Paste_Image.png
但是如果点击确认,没有关闭下面的弹框的话,那么是正常的,比如这样
Paste_Image.png同样的操作,同样的弹框,只是是否把底下的弹框remove掉,就会出现这样的问题,所以可能就是下面的弹框remove的问题?尝试使用了transform:translate3d(0, 0, 0)也没解决。后来还是没找到原因,最后因为是在移动端,所以只能暂时也把弹框的定位改成fixed再居中把原有的定位覆盖就没有问题了。
body div.m-basewin {
position: fixed!important;
top: 50%!important;
transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
}
20、在iphone5s版微信中,flex布局不起作用
由于flex有新老版本的问题,iphone5没有更新flex的写法,所以还是加上老的写法就解决了
ul{
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
background-color: #f2f4f7;
height: 100%;
}
li{
-webkit-box-flex:1;
-webkit-flex:1;
flex: 1;
text-align: center;
}
21、使用fs.readFileSync()读取文件,打包之后中文乱码
使用browserify打包html模板文件,需要用到fs.readFileSync()方法,在编辑器中明确显示是utf-8编码,但是打包后的文件中文乱码。我用的控制台是powerShell,但是使用git bash打包是正常的。原因是控制台的编码跟文件编码不一致导致的。所以只要更改控制台的编码就可以了,解决方法:
中文编码号(GB2312): 936
utf8: 65001
- 运行cmd
- 输入chcp,查看当前的控制台的编码
- 输入chcp 65001,回车,控制台的编码就被设置成了utf8的编码
- 打包之后,中文就不会乱发了
22、在异步请求回调函数中新打开页面或者提交form表单被浏览器拦截
在平常需要做的一些操作可能是需要先发一个请求给后端,在返回的结果做判断之后做一些操作,但是最近发现在异步请求回调中打开新窗口或者提交form表单新打开窗口都会被浏览器拦截。因为浏览器会认为这个是不安全的操作(比如广告之类的)。
解决方法是把异步请求变为同步请求,发请求之后阻断浏览器,回调之后打开窗口,然浏览器认为这两个操作是同一个操作就可以了。或者是异步请求回调之后抛出一个事件,然后结束。在回调外面监听抛出的事件,然后新打开窗口。
23、使用browserify、gulp打包之后会出现在每个字符之间多了一个NUL
为了从gulp打包过度到browserify打包方式,先用browserify把js根据依赖来打包出一个js文件。然后使用gulp把打包出来的js与html再打包成一个html文件。打包出来的html文件出现了乱码
Paste_Image.png原因是两次打包用的编码不一样。还是用的powershell,就是设置了utf8编码,好像打包出来的是uft-16 with BOM的,所以经过gulp再次打包之后就会出现这种情况。所以还是找个cmd编码的统一的。比如git bash打包出来就没有问题。
24、 css3 兼容性写法
// flex
ul {
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
li {
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-flex: 1; /* OLD - Firefox 19- */
width: 20%; /* For old syntax, otherwise collapses. */
-webkit-flex: 1; /* Chrome */
-ms-flex: 1; /* IE 10 */
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
// transform
transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
-webkit-transform: translate(-50%,-50%);
-o-transform: translate(-50%,-50%);
-moz-transform: translate(-50%,-50%);
25、css min-width属性不认auto值,且选择器权重无效。
使用web端的组件,需要覆盖一些样式,在iphone及一些浏览器没有问题,但是在某些安卓手机上,发现尽管权重已经比之前的大,但是不起作用。调试发现,需要覆盖掉的min-width属性的值设置为auto不起作用,查看w3c发现min-width的值没有auto,所以才会出现问题,改为0就好了,选择器权重的问题,不知道什么问题,加!important就好了
26、解决点击浏览器返回按钮不刷新文件,请求头出现provisional headers are shown问题
点击浏览器返回按钮之后,浏览器会从缓存里面读取上一个页面的页面数据,如果此时需要实时更新则会出现问题问题,比如前后两次后端在html中不一样的情况,出现这样的情况可以让后端返回html时带上cache-control缓存头,让浏览器点击返回按钮时,强制去服务器请求新的页面。
以上问题出现常见的现象是request headers出现provisional headers are shown,解释如下
之所以会出现这个警告,是因为去获取该资源的请求其实并(还)没有真的发生,所以 Header 里显示的是伪
信息,直到服务器真的有响应返回,这里的 Header 信息才会被更新为真实的。不过这一切也可能不会发生,
因为该请求可能会被屏蔽。比如说 AdBlock 什么的,当然了不全是浏览器扩展,具体情况具体分析了
当然,如果导致出现provisional headers are shown这个信息的问题有很多,具体参考这篇文章provisional headers are shown
网友评论