原生jsは画像のプレビューとアップロードを実現します

18836 ワード

最近主導したPCクライアントのウェブサイトの再構築工事は一段落し、次の段階で会社のAPPにH 5ページを開発し始め、技術スタックはreactである.最近、H 5ページに身分証明書の写真を追加し、プレビューしてアップロードする必要があるというニーズに遭遇しました.Android 4.4以下のバージョンの携帯電話と互換性があるため、html 5の新しい属性formDataさえ使えず、純原生jsが実現した.
まずinput入力ボックスを取得し、onchangeイベントを登録します. 
uploadImage(){
        let idCardFrontParams={
            showID: "img-box1",
            flag: "idCardFrontFileId"
        };
        let $this=this;
        //     input  
        var idCardFrontFile = document.getElementById("idCardFrontFile");
        idCardFrontFile.onchange = function () {
            let that = this;
            $this.preview(that, idCardFrontParams);
        };
    }

次に、アップロードとプレビュー機能を実現し、プレビューの鍵はgetobjectURLメソッドを使用してアップロードされた画像のurlアドレスを取得することです.URL.createObjectURL()メソッドは、入力されたパラメータに基づいて、そのパラメータオブジェクトを指すURLを作成します.このURLの生命は、作成されたこのドキュメントにのみ存在し、新しいオブジェクトURLは実行されるFileオブジェクトまたはBlobオブジェクトを指します.この構文は、objectURL=windowです.URL.createObjectURL(blob || file);ブラウザによって違いがあります
画像urlを取得してフォームを呼び出す方法submitは、それをアップロードし、指定したdivにアドレスを割り当てます.
preview(that, options) {
        //  files    
        let _file = that.files,$this=this;
        if(_file[0]){
            let addr = getObjectURL(_file[0]);
            let curFile=options.flag;
            this.setState({isLoading:true});
            document.querySelector("#"+curFile).submit();
            if(curFile==="deviceFileId"){
                $this.setState({deviceFile:true});
            }else if(curFile==="idCardFrontFileId"){
                $this.setState({idCardFrontFile:true});
            }else if(curFile==="idCardbackFileId"){
                $this.setState({idCardBackFile:true});
            }

            var fileUpIframe = document.getElementById("file_upload_iframe");
            fileUpIframe.onload = fileUpIframe.onreadystatechange =  function () {
                try {
                    var data = JSON.parse(fileUpIframe.contentWindow.document.body.innerHTML);
                    if (data.code) {
                        $this.submitParams[curFile]="";
                        alert("      ,       !");
                    } else {
                        $this.submitParams[curFile]=data.fileId;
                    }
                    $this.setState({isLoading:false});
                }catch (err){
                    console.warn(err);
                }
            }
            let dom =document.getElementById(options.showID);
            dom.style.backgroundImage = "url("+addr+")";
        }
        function getObjectURL(file) {
            let url = null;
            if (window.createObjectURL != undefined) { // basic
                url = window.createObjectURL(file);
            } else if (window.URL != undefined) { // mozilla(firefox)
                url = window.URL.createObjectURL(file);
            } else if (window.webkitURL != undefined) { // webkit or chrome
                url = window.webkitURL.createObjectURL(file);
            }
            return url;
        }
    }

ここでは、最も元のフォームコミットが採用されているため、submitメソッドがコミットされるとジャンプし、ajaxがコールバック関数を使用して戻り値を取得できるわけではないので、フォームコミット後の戻り値をtargetでキャリア戻り値を指すiframeが必要です.
"/eyeplus/api/upload" method="post" encType="multipart/form-data" id="idCardbackFileId" target="file_upload_iframe"> "idCardBackFile" type="file" accept="image/*" multiple="multiple" name="file" className="uploadImg"/> "text" className="ub-hidden-ele ub-token" readOnly="readOnly" name="token" value={this.submitParams.token}/> "text" className="ub-hidden-ele ub-clientId" readOnly="readOnly" name="client_id" value={this.submitParams.client_id}/> "text" className="ub-hidden-ele ub-deviceId" readOnly="readOnly" name="device_id" value={this.submitParams.device_id}/> "text" className="ub-hidden-ele ub-type" readOnly="readOnly" name="type" value="201" />

サーバが正しくアップロードすることを確認した後の、使い方JSON.parse(fileUpIframe.contentWindow.document.body.innerHTML)は、サーバの戻り値を解析し、他の必要なパラメータと組み合わせることで、次の操作を快適に行うことができます.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
以上の方法は需要開発を完了することができるが、後続のテストで一つの問題を発見した:IOS携帯電話は問題ないが、Android携帯電話では、戻るときにiframeの存在により、マルチレベルのページが変化するがページの内容は変化していないため、戻るときに正確に戻ることはできない.これは大きな穴だと言わざるを得ませんが、繰り返し実践して、次の方法を採用して順調にテストに合格しました.
preview(that, options) {
        //  files    
        let _file = that.files, $this = this;
        if (_file[0]) {
            let addr = getObjectURL(_file[0]);
            let curFile = options.flag;
            this.setState({isLoading: true});
            if (curFile === "deviceFileId") {
                $this.setState({deviceFile: true});
            } else if (curFile === "idCardFrontFileId") {
                $this.setState({idCardFrontFile: true});
            } else if (curFile === "idCardbackFileId") {
                $this.setState({idCardBackFile: true});
            }
            let dom = document.getElementById(options.showID);
            dom.style.backgroundImage = "url(" + addr + ")";

            let frameId = 'uploadFrame'+ new Date().getTime();
            let fileUpIframe = document.createElement("iframe");
            fileUpIframe.id = fileUpIframe.name = frameId;
            fileUpIframe.style.display = 'none';
            document.body.appendChild(fileUpIframe);
            //let fileUpIframe = document.getElementById("file_upload_iframe");
            fileUpIframe.onload = fileUpIframe.onreadystatechange = function () {
                try {
                    var data = JSON.parse(fileUpIframe.contentWindow.document.body.innerHTML);
                    if (data.code) {
                        $this.submitParams[curFile] = "";
                        alert($this.props.locale.ub_fail_upload);
                    } else {
                        $this.submitParams[curFile] = data.fileId;
                    }
                    $this.setState({isLoading: false});
                    document.body.removeChild(fileUpIframe);
                } catch (err) {
                    console.warn(err);
                }
            };
            let form = document.querySelector("#" + curFile);
            form.target = frameId;
            form.submit();
        }

つまり、HTMLドキュメントに存在するiframeを削除してから、アップロードをプレビューするときにiframeを作成し、アップロード時にフォームに提出されたtargetを変更してiframeのIDを新規作成し、アップロードが完了したらデータを取得してこのiframeを削除し、単一ページにマルチレベルページがあるという問題を回避します.
 
転載先:https://www.cnblogs.com/keang001/p/9034934.html