IE9在vue下的一些兼容

初体验

刚入职新公司一个月,从nodejs转战前端,感觉有趣又有挑战。这一个月来,使用vue前端框架做了一个小型项目,收获满满,在兼容
IE9方面也有很多收获,这些都是之前没有实战接触过的经验,十足珍贵。以下做一下阶段总结,这样后续再遇到问题就能很快处理。
顺便说一下,我发现,做前端经验很重要,刚毕业面试的时候,你问我这些兼容性那些兼容性,一个写不出来,写出来也是背的,现在
问我,我说出来的都是我切切实实遇到的。

placeholder兼容IE9

placeholder属性是html5的新属性,IE9及以下不支持。所以使用focus和blur模拟placeholder。
当focus的时候将input2隐藏,blur的时候将真实的input隐藏,IE9对jquery也有很多不支持,所以不用jquery,原生的js也有很多是IE9不支持的,所以直接用vue的v-model属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import $ from 'jquery';
import Vue from 'vue';
// 标签需要有id和class,class用于编写样式,id用于命名
function FauxPlaceholder(el, binding) {
if(!ElementSupportAttribute('input','placeholder')) {
var $input = $(el);
// 由于vue组件打上了data-v-xx属性,所以复制的时候需要把该属性一并复制过来,才能实现动态绑定class
const clone = $input.clone();
clone.removeAttr('v-placeholder').removeAttr('type').removeAttr('placeholder')
.attr('value', $input.attr('placeholder'))
.attr('id', $input.attr('id')+ '-faux')
.attr('style', "display:none;")
.attr('type', 'text');
$input.after(clone);
var $faux = $('#'+$input.attr('id')+'-faux');
$faux.show().attr('class', $input.attr('class'));
$input.hide();
$faux.focus(function() {
$faux.hide();
$input.show().focus();
});
$input.blur(function() {
if($input.val() === '') {
$input.hide();
$faux.show();
}
});
}
}
// 检查标签是否支持该属性
function ElementSupportAttribute(elm, attr) {
var test = document.createElement(elm);
return attr in test;
}
export default {
inserted: function(el, binding){
FauxPlaceholder(el, binding);
}
}

360兼容模式下IE低版本的console问题

最近在发布测试vue项目的时候,发现火狐支持,IE9标准模式支持,360极速模式支持,但是360兼容模式不支持,且页面没有任何报错,就是不显示组件,神奇的是,按f12,然后啥也不做,刷新页面就可以正常显示了,这是为啥勒?多方咨询后,发现是由于360浏览器在兼容模式下包含IE低版本,而IE低版本是不支持console的,所以尝试把你代码中的console去掉吧!打包发布,boom!!!没有错了。那有时候会不小心遗留console在生产环境的代码中,解决方法就是在入口文件中加入这段代码

1
2
3
4
5
6
window.console = window.console || (function () {
const c = {};
c.log = c.warn = c.debug = c.info = c.error = c.time = c.dir = c.profile
= c.clear = c.exception = c.trace = c.assert = function () {};
return c;
}());

分页组件

参考这个 https://segmentfault.com/a/1190000003931500

IE9下面hover触发兄弟元素兼容 hover自定义组件

自定义指令v-hover

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div class="test1" v-hover="{ele: '#test2'}"></div>
<div id="test2"></div>
Vue.directive('hover', {
inserted: function (el, binding) {
$(el).hover(function(){
let el2 = $(`${binding.value.ele}`);
if(el2.css("display") === 'none'){
el2.css("display", "block");
} else{
el2.css("display", "none");
}
});
}
})

vue-router处于hash模式时候的锚点不支持解决方案

单页面应用需要在页面不刷新的情况下,通过更改地址栏url实现不同路由的切换,有两个api可以使用:

采用 location.hash 实现hash(#号)URL路由判断
采用 HTML5中的 history.pushState() 方法
两种方式各有特点,第一个兼容性较好,可以在各种浏览器中运行,但是URL中会有一个#,看起来不好看,第一个是HTML5属性,只能在现代浏览器中运行;

vue-router配置路由模式,分为两种, hash 和 history,当浏览器不支持 history时,即使设置为 histroy 模式,仍然使用 hash 模式。通过判断history.pushState是否为真来配置模式。

监听路由,在浏览器的url改变时,获取到#后面的hash值,location.hash默认返回的是带#号的hash,需要去掉#号,然后获取到的参数就可以匹配路由,并执行路由处理函数。

所以,重点就在这个hash模式下面的#号。假设有个路径是www.mywebsite.com/#/foo?bar=baz,那么其hash值就是#/foo?bar=baz,那如果有锚点www.mywebsite.com/#/foo?bar=baz#anchor,那么可以hash值就是#anchor,也就是锚点,此时点击锚点不能直接使用href改变url,应该使用拼接的完整地址,否则hash模式下面浏览器会直接解析成www.mywebsite.com/#/anchor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<a @click.stop="toAnchor('anchor')">点击到锚点</a>
beforeRouteUpdate(to, from, next){
if (to.hash !== '') {
const id = to.hash.replace('#', '');
const element = document.getElementById(id);
if (element) element.scrollIntoView();
}
next();
}
methods: {
toAnchor(key){
const url = document.location.href.split('#');
this.$router.push(`${url[1]}#${key}`);
}
}

列表渲染

检测数组的变化,当你利用索引直接设置一个项时, vm.items[indexOfItem] = newValue无效,使用Vue.set(example1.items, indexOfItem, newValue)或者example1.items.splice(indexOfItem, 1, newValue)替代。当你修改数组的长度时,例如: vm.items.length = newLength无效,使用example1.items.splice(newLength)替代。

官网看这里

精度问题

http://www.cnblogs.com/snandy/p/4943138.html

两个浮点数相加,会出现精度丢失问题,是由于计算机编程语言里浮点数计算会存在精度丢失问题(或称舍入误差),其根本原因是二进制和实现位数限制有些数无法有限表示,整数和小数都会出现精度丢失,但是小数出现的频率在前端页面会更多点。例如0.01的加减问题。
使用(0.03 100 - 0.01 100) / 100是无效的,还是会出现精度问题

1
2
3
(Math.round(0.29*100)+1)/100
parseFloat(1.00); // 1
parseFloat(1.01); // 1.01
如果您觉得受益了,欢迎打赏鼓励。