神州之心項(xiàng)目總結(jié)

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)目中

image

然后在頁(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í)使用


QQ截圖20180119164830.png
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)目中的其他的彈窗等

例如:
QQ截圖20180119172736.png
就會(huì)產(chǎn)生如下情況:
QQ截圖20180119172653.png

解決辦法,針對(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í)別*/
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容