ie8的css兼容性問(wèn)題
1.不支持box-shadow屬性。
解決方法:
使用-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#C7C9CD')";
說(shuō)明:strength是陰影大小,direction是陰影方位,單位為度,可以為負(fù)數(shù),color是陰影顏色 (不支持rgba格式)使用IE濾鏡實(shí)現(xiàn)盒子陰影的盒子必須是行元素或以行元素顯示(block或inline-block;)
box-shadow: 0 5px 10px rgba(33,36,41,0.2);/* for opera or ie9 */
-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#C7C9CD')";
2.不支持rgba()格式的顏色
如果設(shè)置的背景色有一個(gè)透明度,則ie8及以下都不支持
解決辦法:使用filter濾鏡設(shè)置漸變。設(shè)置startColorstr和stopColorstr為相同的顏色,相同的透明度,即可達(dá)到半透明的背景效果。其中顏色字符串中,第1,2個(gè)字符表示透明度,例如當(dāng)前的7f表示0.5的透明度,其他值自行去查;后面6個(gè)字符既是顏色的十六進(jìn)制格式。
background-color: rgba(29,61,103,.5);
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#7f1D3D67,endColorstr=#7f1D3D67);
3.不支持opacity屬性
解決方法: 使用filter濾鏡。注意:在使用filter濾鏡設(shè)置不透明度時(shí),需要給該元素設(shè)置背景色,否則設(shè)置的不透明度將沒(méi)有任作用。這個(gè)屬性一旦設(shè)置成功,那么該屬性里的元素或者文字都會(huì)有設(shè)置的透明度。
background: #fff;
opacity: 0;
filter: alpha(opacity=0);/*兼容ie8及以下*/
4.常用的css3選擇器的支持性
1)支持:first-child,不支持:last-child選擇器,盡量避免使用last-child選擇器 。
2)支持:after和:before選擇器
3) 不支持:nth-child選擇器
4)不支持:not()選擇器
5)不支持:checked,:disabled
6)支持屬性選擇器,如[attribute^=value],[attribute$=value],[attribute*=value]等
5.不支持border-radius屬性
解決方法,可通過(guò)pie.js補(bǔ)丁文件解決
下載pie補(bǔ)丁文件,放入項(xiàng)目中

然后在頁(yè)面中引用
<!-- [if it ie 9] -->
<!-- <script src="/static/plugins/pie/PIE.js"></script> -->
<!-- <[!endif] -- >
在css中使用:
border-radius: 4px;
behavior: url(/static/plugins/pie/PIE.htc);
但是使用這個(gè)補(bǔ)丁可能會(huì)有一些意想不到的問(wèn)題,所以根據(jù)實(shí)際情況而定
6.ie9及以下都不支持漸變
解決方法:使用如下方法代替。startColorstr,endColorstr漸變的開(kāi)始顏色和結(jié)束顏色,格式是AARRGGBB,gradiendtType是漸變的方向,1是水平漸變,0是垂直漸變。
progid:DXImageTransform.Microsoft.gradient(startColorstr='#B2FFFFFF',endColorstr='#00FFFFFF',GradientType=0 );
7.其他屬性兼容性說(shuō)明
1)ie9及其以下都不支持css3的@keyframe 規(guī)則或 animation 屬性,盡量避免使用
2)不支持css3的transform屬性(ie9支持代替的-ms-transform屬性,僅適用于2D轉(zhuǎn)換
3)不支持background-size屬性和border-image屬性
8.不支持canvas,和svg
解決方法:使用vml代替,繪制圖形
9.不支持placeholder屬性
解決方法:自己寫(xiě)一個(gè)input組件,使用blur和focus事件來(lái)實(shí)現(xiàn)placeholder的效果。
import styles from './index.scss';
import React, { Component } from 'react';
import classNames from 'classnames';
class Input extends Component {
constructor(props) {
super(props);
this.state = {
supportPlaceholder: false
};
}
/**
* @param input 輸入框
* @param text placeholder
*/
placeholder = (input, text = '') =>{
var defaultValue = input.defaultValue;
if(!defaultValue){
input.val(text).addClass('phcolor');
}
input.unbind('focus', 'F');
input.unbind('blur');
input.focus(function F(){
if(input.val() === text){
$(this).val('');
}
});
input.blur(function(){
if(input.val() === ''){
$(this).val(text).addClass('phcolor');
}
});
// 輸入的字符不為灰色
input.keydown(function(){
$(this).removeClass('phcolor');
});
}
componentDidMount() {
let THIS = this;
let self = this.textInput;
this.props.callback && this.props.callback();
$(function(){
// 判斷瀏覽器是否支持placeholder屬性
var supportPlaceholder = 'placeholder' in document.createElement('input');
if(!supportPlaceholder){
if($(self).attr('type') === 'text'){
THIS.placeholder($(self), THIS.props.placeholder);
}
}
});
}
componentDidUpdate(){
let supportPlaceholder = 'placeholder' in document.createElement('input');
let self = this.textInput;
let THIS = this;
if($(self).val() || document.activeElement === this.textInput){
return false;
}
if(!supportPlaceholder){
if($(self).attr('type') === 'text'){
THIS.placeholder($(self), THIS.props.placeholder);
}
}
}
render() {
const { supportPlaceholder } = this.state;
let {className, style, ...other} = this.props;
style = style || {
// height: '40px',
// width: 'auto'
};
return (
<input
type="text"
className={classNames('input', 'border_color_gray', 'synBlockBg', className)}
{...other}
style={style}
ref={(input) => { this.textInput = input; }}
/>
);
}
}
export default Input;
ie8的javascript兼容性問(wèn)題
1.不支持indexOf()方法和trim()方法
在全局js中給string對(duì)象添加這兩個(gè)方法,具體如下
if (!Array.prototype.indexOf){
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
}
2.不支持es6語(yǔ)法,只支持部分es5的語(yǔ)法
解決方法,使用es3ifyPlugin插件,講es5和es6的語(yǔ)法編譯成es3,讓ie8完全支持
在配置文件中添加該插件
plugins: [
extractVendor,
extractStyle,
new es3ifyPlugin(),
...
]
項(xiàng)目中遇到的問(wèn)題
1.餅圖默認(rèn)選中某條數(shù)據(jù)的功能實(shí)現(xiàn)
-
想要達(dá)成的效果:如圖,頁(yè)面加載完成之后,默認(rèn)選中最大數(shù)據(jù)的那一項(xiàng),當(dāng)鼠標(biāo)移到其他項(xiàng)時(shí),取消默認(rèn)選中,當(dāng)鼠標(biāo)移開(kāi)圖表時(shí),回復(fù)圖表的默認(rèn)選中。
QQ截圖20180119155953.png - 實(shí)現(xiàn)方法
默認(rèn)選中時(shí),使用圖表實(shí)例的dispatchAction()方法,代碼如下。
/**
* 初始選中最大數(shù)據(jù)
*/
initBigData = (pieChart = this.pieChart.getEchartsInstance()) => {
const {heightLight} = this.state;
if(heightLight){
setTimeout(() => { // 由于在執(zhí)行此方法的時(shí)候,圖表不一定就渲染完畢,所以設(shè)置了一個(gè)定時(shí)器
pieChart.dispatchAction({
type: 'highlight', // 選中
name: heightLight // 選中的項(xiàng)的名字,這里是“私營(yíng)企業(yè)”
});
}, 10);
}
}
方法使用示例,在圖表init了之后,獲取到實(shí)例后,再執(zhí)行該方法,
renderEchartDom(flag) {
let echartObj = echarts.init(this.echartsDom, themeStrSession);
echartObj.setOption(this.props.option, true, true);
initBigData && initBigData (echartObj); // 餅圖默認(rèn)選擇最大的值
return echartObj;
}
移除圖表再恢復(fù)默認(rèn)選中的方法
/**
* 取消餅圖某個(gè)模塊的選中狀態(tài)
*/
reSet = () => {
const {heightLight} = this.state;
if(heightLight){
this.pieChart.getEchartsInstance().dispatchAction({
type: 'downplay', // 取消選中的標(biāo)識(shí)
name: heightLight // 取消選中項(xiàng)的名字
});
}
}
使用時(shí),給圖表的外框加一個(gè)鼠標(biāo)移除的事件(mouseleave),在該事件的方法中執(zhí)行reSet()方法即可。
注意:mouseleave()和mouseout()方法的區(qū)別.
mouseout 事件在鼠標(biāo)指針離開(kāi)被選元素或任意子元素時(shí)都會(huì)被觸發(fā),mouseleave 事件只有在鼠標(biāo)指針離開(kāi)被選元素時(shí)被觸發(fā)。
2.echarts圖標(biāo)的主題色切換
在項(xiàng)目中,有些時(shí)候設(shè)計(jì)到換膚的功能,一套淺色一套深色,這個(gè)時(shí)候,echarts圖表的主題該怎么設(shè)置才能滿足要求呢。
這時(shí)我們使用echarts主題色,配置兩套主題,一套深色主題,一套淺色主題,(具體主題色的配置自行查閱)在init方法時(shí)使用

require('./echartDarkTheme'); // 引入深色主題
require('./echartLightTheme'); // 引入淺色主題
getEchartsInstance() {
const themeStrSession = sessionStorage.getItem('skinNum') === 'dark' ? 'echartDarkTheme' : 'echartLightTheme';
return echarts.init(this.echartsDom, themeStrSession);
}
3.react事件和原生事件混用所產(chǎn)生的問(wèn)題
react事件是合成事件,使用了事件委托的方法,將所有的事件綁定在了document上,并且在事件冒泡的過(guò)程中執(zhí)行對(duì)應(yīng)的回調(diào)方法。而原生事件是直接綁定在了dom上,所以,當(dāng)一個(gè)dom上用了react綁定了事件,有用原生方法綁定了事件之后,我們并不能確定是哪一次綁定的回調(diào)函數(shù)會(huì)先執(zhí)行,因此會(huì)有很多意想不到的問(wèn)題,所以我們要盡量避免react和原生事件混用的情況。
4.前端輪詢監(jiān)聽(tīng)報(bào)報(bào)告是否生成或下載成功
在生成一個(gè)報(bào)告的過(guò)程中,怎么監(jiān)聽(tīng)報(bào)告什么時(shí)候生成完畢呢,在前端的話,我們需要輪詢
監(jiān)聽(tīng)方法
/**
* 監(jiān)聽(tīng)是否生成成功
*/
addListerReport = () => {
const reportInfo = JSON.parse(JSON.stringify(this.state.reportInfo));
const {intervalTime} = this;
addListerReport({
reportId: reportInfo.reportId
}).then(data => {
if(!data.success){
return messager.error('報(bào)告生成失敗,請(qǐng)重新生成!');
}
if(data.data) {
reportInfo.reportStatus = 'SUCCESS';
clearInterval(intervalTime);
// clearTimeout(outTime);
this.setState({
operateText: '',
reportInfo
});
}
});
}
方法的調(diào)用
/**
* 點(diǎn)擊生成報(bào)告
*/
reGenerateReport = (isNewReport) => {
const reportInfo = JSON.parse(JSON.stringify(this.state.reportInfo));
const {companyId, reportTime, companyName} = reportInfo;
generateReport({
companyId,
companyName,
remakes: isNewReport
}).then(data => {
if(!data.success) {
return messager.error('生成失敗,請(qǐng)重新生成!');
}
this.intervalTime = setInterval(() => { // 輪詢調(diào)用監(jiān)聽(tīng)方法,每個(gè)5秒調(diào)用一次
this.addListerReport();
}, 5000);
});
}
注意:在組件卸載之前要先清除該定時(shí)器,否則該方法會(huì)一直執(zhí)行
componentWillUnmount() {
const {intervalTime, outTime} = this;
clearInterval(intervalTime);
}
5.地圖下潛和返回是總有一種閃現(xiàn)的情況
該情況主要產(chǎn)生的原因是,在下潛時(shí),省的名已經(jīng)傳遞給了下層組件,用于繪制,但此時(shí),該省的地圖json數(shù)據(jù)還沒(méi)有拿到,這時(shí)如果其他地方使用了setState,發(fā)生了render的話那么下層組件就會(huì)重新繪制地圖,但是由于省的名字和地圖json數(shù)據(jù)對(duì)應(yīng)不上,就又一次繪制了全國(guó)地圖,這時(shí)就會(huì)有一個(gè)中間的過(guò)程,導(dǎo)致地圖閃一下才會(huì)繪制出對(duì)應(yīng)的省的地圖。
解決辦法,省的名字和地圖的json數(shù)據(jù)同時(shí)設(shè)置,并且同時(shí)使用,盡量避免沒(méi)有必要的渲染。例如:這里一起設(shè)置了三個(gè)值之后,進(jìn)行渲染,就不會(huì)產(chǎn)生跳動(dòng)的情況
$.getJSON(mapUrl, (mapjson) => {
this.setState({
jsonData: mapjson, // 地圖的json數(shù)據(jù)
mapChinaOption: option, // option對(duì)象
province: this.mapInfo.province }); // 下潛的省市名稱(chēng)
});
6.ie8下使用vml繪制的圖表的層級(jí)問(wèn)題
ie8不支持canvas,所以我們使用vml來(lái)代替繪制圖表。但是其繪制出來(lái)的圖表的層級(jí)很高,導(dǎo)致了其覆蓋了我們項(xiàng)目中的其他的彈窗等


解決辦法,針對(duì)ie8,單獨(dú)設(shè)置彈窗的層級(jí)
.bg{
...
opacity: 0.4
z-index: 1000;
z-index: 50020\9;/*給背景蒙層設(shè)置層級(jí) IE6、7、8識(shí)別*/
filter: alpha(opacity=40);
}
.wrap{
...
z-index: 1000;
z-index: 50020\9;/*給彈窗的外層設(shè)置層級(jí) IE6、7、8識(shí)別*/
}
