この記事は主に、みんなで共有できるVue3ベースのフルスクリーンドラッグアップロードコンポーネントを紹介します。詳細は次のとおりです。 知識ポイント
長い話になりますが、簡単に言うと、HTML5 ドラッグ API を使用したドラッグ アンド ドロップ ソートの例をいくつか紹介しただけです。実際、考え方は他のドラッグ アンド ドロップ アップロード コンポーネントと基本的に同じで、ドラッグする領域を指定して、ファイルを読み込んでアップロードします。まずは、HTML5 の新しい API であるドラッグ API についてお話ししましょう。要素に draggable = true 属性を設定すると、その要素はドラッグをサポートします。ドラッグ要素のイベントは次のとおりです。 1. ondragは要素をドラッグするときにスクリプトを実行します 対象要素のイベントは次のとおりです。 たとえば、ボディの引きずりを監視したいとします。 const ele = document.querySelector('body') ele.addEventListener('dragenter', (e) => { // 何かをする }) デフォルトイベントを防止したい場合は、e.preventDefault() を使用します。 コンポーネントまずは効果を見てみましょう。今回はpngとjpgのみアップロードするように設定しました 使用: <アップロード accept=".jpg,.png,.ico" // ファイルタイプを設定 @onChange="change" // ファイルアップロードイベント action="http://localhost:3001/upload" // アップロードアドレス: header="header" // アップロードされたヘッダー autoUpload // 自動的にアップロードするかどうか name="file" // アップロードされたフィールド名 @onSuccess="onSuccess" // アップロード成功コールバック></upload> 当初、ドラッグされた要素を取得したいときに、リスニング イベントを追加しても、ファイルをプレビューするために新しいウィンドウが開かれることがわかったので、最初のステップとして、すべてのデフォルト イベントを無効にしました。 // デフォルトのドラッグイベントを無効にする function enableDefaultEvents() { 定数doc = document.documentElement doc.addEventListener('dragleave', (e) => e.preventDefault()) //ドラッグして離すdoc.addEventListener('drop', (e) => e.preventDefault()) //ドラッグしてドロップdoc.addEventListener('dragenter', (e) => e.preventDefault()) //ドラッグして入れるdoc.addEventListener('dragover', (e) => e.preventDefault()) //前後にドラッグ} ドラッグのデフォルトイベントを防ぐためにルート要素を直接取得する 2 番目のステップは、監視するイベントを本体またはその他の要素に追加することです。ここで注意すべき点は、フルスクリーン ドラッグが実現できるように、本体の高さはウィンドウの高さと同じでなければならないということです。ドラッグするときに、ファイルが領域外にドラッグされているかどうかも判断する必要があります。 全体的な判決は次のとおりです。 e.target.nodeName === 'HTML'、これはルート要素がHTMLであるかどうかを判断するために使用されます e.target === e.explicitOriginalTarget これは、2つのトリガーイベントのターゲットが一致しているかどうかを判定するFirefox固有のAPIです(!e.fromElement && (e.clientX <= 0 || e.clientY <= 0 || e.clientX >= window.innerWidth || e.clientY >= window.innerHeight)) これは、マウスの現在の位置、つまりマウスがまだエリア内にあるかどうかを判断するために使用されます。 // ドラッグイベント関数を初期化する init() { // 本文要素を取得する const ele = document.querySelector('body') // イベントを追加 // ドラッグアンドドロップ ele.addEventListener('dragenter', () => { 表示値 = true }) // ここでマウスがドラッグされているかどうかを判断しますele.addEventListener('dragleave', (e) => { もし ( e.target.nodeName === 'HTML' || e.target === e.explicitOriginalTarget || (!e.fromElement && (e.clientX <= 0 || e.clientY <= 0 || e.clientX >= window.innerWidth || e.clientY >= window.innerHeight)) ){ 表示値 = false } }) //ドラッグ inele.addEventListener('drop', (e) => { 表示値 = false e.preventDefault() onDrop(e) // ファイルをドラッグして処理するメソッド}) } 3 番目のステップは、ドラッグされたファイルを処理することです。この時点で、 accept は定義したファイル タイプです。この時点で、ドラッグされたファイルを取得するために e.dataTransfer.files プロパティを使用できます。 checkType(file,accept) はファイルタイプを判定するために使用されます。この関数は、element ui のアップロードコンポーネントのフィルターに基づいています。私もこれを書いたときは混乱しました。 // ファイルタイプをチェックする function checkType(file, accept = '') { const { 型, 名前 } = ファイル (accept.length === 0) の場合は true を返す const extension = name.indexOf('.') > -1 ? `.${name.split('.').pop()}` : '' const baseType = type.replace(/\/.*$/, '') 返品 承諾 。スプリット('、') .map((type) => type.trim()) .filter((type) => type) .some((受け入れられたタイプ) => { if (/\..+$/.test(acceptedType)) { 戻り値の拡張子 === acceptedType } if (/\/\*$/.test(acceptedType)) { baseType === acceptedType.replace(/\/\*$/, '') を返します } (/^[^/]+\/[^/]+$/.test(acceptedType)) の場合 { 戻り値の型 === acceptedType } }) } このメソッドは、ファイルがドラッグされた後にそのファイルを処理するために使用されます。必要なファイルを取得したら、autoUpload を使用してアップロードするかどうかを決定します。 関数onDrop(e) { 定数 accept = props.accept const list = [].slice.call(e.dataTransfer.files).filter((ファイル) => { (受け入れる)場合{ checkType(file, accept) を返します } 真を返す }) ファイルリスト = list.map((p) => { handleStart(p) を返す }) // イベント onChange() をトリガーする props.autoUploadの場合{ props.action === ''の場合{ エラー発生時() 「行動が必要」を投げる 戻る } list.forEach((ファイル) => { post(file) // ファイルをアップロードする }) } } ソースコードは次のとおりです。 <テンプレート> <div class="mask" v-show="show" id="mask"> <h3>アップロードするにはここにドラッグしてください</h3> </div> </テンプレート> <スクリプトの設定> 'vue' から { ref, reactive, onMounted } をインポートします。 // './ajax' から ajax をインポートします const props = defineProps({ name: String, // アップロードされたフィールド名 header: { Object, Number, String }, // アップロードされたファイルのヘッダー // 検証するファイルタイプ、値がある場合、すべてのファイルのみがドラッグされ、フィルター設定後のファイルのみが保持されます accept: { タイプ: 文字列、 デフォルト: ''、 }, // 自動アップロードを有効にするかどうか autoUpload: { タイプ: ブール値、 デフォルト: false、 }, // アドレスのアップロードアクション: { タイプ: 文字列、 デフォルト: '#'、 }, }) const emitting = defineEmits(['onError', 'onProgress', 'onSuccess', 'onChange']) // デフォルトのemitイベント let show = ref(false) // マスクを表示するかどうか let fileList = reactive([]) // ファイルリスト let tempIndex = 0 // マークを付ける onMounted(() => { デフォルトイベントを無効にする() 初期化() }) // ドラッグイベント関数を初期化する init() { const ele = document.querySelector('body') ele.addEventListener('dragenter', () => { 表示値 = true }) //ドラッグアンドドロップele.addEventListener('dragleave', (e) => { もし ( e.target.nodeName === 'HTML' || e.target === e.explicitOriginalTarget || (!e.fromElement && (e.clientX <= 0 || e.clientY <= 0 || e.clientX >= window.innerWidth || e.clientY >= window.innerHeight)) ){ 表示値 = false } }) //ドラッグして離れるele.addEventListener('drop', (e) => { 表示値 = false e.preventDefault() ドロップ時 }) // ドラッグイン } // デフォルトのドラッグイベントを無効にする function enableDefaultEvents() { 定数doc = document.documentElement doc.addEventListener('dragleave', (e) => e.preventDefault()) //ドラッグして離すdoc.addEventListener('drop', (e) => e.preventDefault()) //ドラッグしてドロップdoc.addEventListener('dragenter', (e) => e.preventDefault()) //ドラッグして入れるdoc.addEventListener('dragover', (e) => e.preventDefault()) //前後にドラッグ} //ドラッグインイベント関数onDrop(e) { 定数 accept = props.accept const list = [].slice.call(e.dataTransfer.files).filter((ファイル) => { (受け入れる)場合{ checkType(file, accept) を返します } 真を返す }) ファイルリスト = list.map((p) => { handleStart(p) を返す }) 変更時() props.autoUploadの場合{ props.action === ''の場合{ エラー発生時() 「行動が必要」を投げる 戻る } list.forEach((ファイル) => { 投稿(ファイル) }) } } // ファイルタイプをチェックする function checkType(file, accept = '') { const { 型, 名前 } = ファイル (accept.length === 0) の場合は true を返す const extension = name.indexOf('.') > -1 ? `.${name.split('.').pop()}` : '' const baseType = type.replace(/\/.*$/, '') 返品 承諾 。スプリット('、') .map((type) => type.trim()) .filter((type) => type) .some((受け入れられたタイプ) => { if (/\..+$/.test(acceptedType)) { 拡張子を返す === acceptedType } if (/\/\*$/.test(acceptedType)) { baseType === acceptedType.replace(/\/\*$/, '') を返します } (/^[^/]+\/[^/]+$/.test(acceptedType)) の場合 { 戻り値の型 === acceptedType } }) } // ファイルリストの戻り値を処理する function handleStart(rawFile) { rawFile.uid = Date.now() + tempIndex++ 戻る { ステータス: '準備完了'、 名前: rawFile.name、 サイズ: rawFile.size、 パーセンテージ: 0, uid: rawFile.uid、 生: 生ファイル、 } } //アップロードイベント関数 post(rawFile) { 定数オプション = { ヘッダー: props.header、 ファイル: rawFile、 データ: props.data || ''、 ファイル名: props.name || 'ファイル', アクション: props.action、 } アップロード(オプション) .then((res) => { res.json() }) .then((json) => { 成功時(json、rawファイル) }) .catch((エラー) => { エラーが発生した場合(エラー、rawFile) }) } // ファイルアップロードメソッド function upload(option) { const アクション = オプション.アクション const フォームデータ = 新しいフォームデータ() if (オプション.データ) { Object.keys(option.data).forEach((key) => { formData.append(キー、オプション.data[キー]) }) } formData.append(オプション.ファイル名, オプション.ファイル, オプション.ファイル名) const ヘッダー = 新しいヘッダー() for (let 項目をヘッダーに) { headers.hasOwnProperty(item) && headers[item] !== null の場合 { ヘッダーを追加します(i, オプション.ヘッダー[i]) } } 戻り値: fetch(action, { モード: 'no-cors'、 本文: フォームデータ、 ヘッダー: ヘッダー、 メソッド: 'post'、 }) } // ドラッグしてファイルリストイベントを取得します function onChange() { 出力('onChange', ファイルリスト) } //アップロードイベント関数 onProgress(e, file) { 出力('onProgress', e, ファイル, ファイルリスト) } // アップロード成功イベント関数 onSuccess(res, file) { 出力('onProgress', res, ファイル, ファイルリスト) } // アップロード失敗イベント関数 onError() { 出力('onError') } </スクリプト> <スタイルスコープ> 。マスク { 上: 0; 下部: 0; 右: 0; 左: 0; 位置: 固定; zインデックス: 9999; 不透明度: 0.6; テキスト配置: 中央; 背景: #000; } h3 { マージン: -0.5em 0 0; 位置: 絶対; 上位: 50%; 左: 0; 右: 0; -webkit-transform: translateY(-50%); -ms-transform: 変換Y(-50%); 変換: translateY(-50%); フォントサイズ: 40px; 色: #fff; パディング: 0; } </スタイル> これで、Vue3 ベースのフルスクリーン ドラッグ アンド ドロップ アップロード コンポーネントに関するこの記事は終了です。Vue3 フルスクリーン ドラッグ アンド ドロップ アップロードに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
CSS3 の角丸や影の効果を使ったページを作りたいのですが、IE ブラウザでは対応していません。こ...
モバイル ブラウザは、Web ページを仮想の「ウィンドウ」(ビューポート) に配置します。このウィン...
目次使用シナリオ解決1. globalDataを使用して実装する2. ローカルキャッシュストレージを...
Vue 3.x プロジェクトの作成 npm init @vitejs/app my-vue-app ...
Docker はコンテナを作成するときに、デフォルトでブリッジ ネットワークを使用し、IP アドレス...
目次背景は次のとおりです。何が起こるでしょうか?背景は次のとおりです。実際の開発では、ネットワークの...
目次ライフサイクルの変化反応的な参照vue2.x では ref を使用して要素タグを取得します。vu...
数日前、私のウェブサイトがいくつかの IP アドレスから大量の悪意のある標的型スキャンを受け、ブルー...
ステップ1: Alibaba Cloudプライマリドメイン名にセカンダリドメイン名を追加する2 番目...
01 ウィンターフレーク(個人のみ) 02 スノートップキャップ(業務用) 03 モディウス「フリ...
1. はじめに最近、あるプロジェクトに取り組んでいたのですが、サーバーからクライアントに返される J...
123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...
目次1. setTimeout() タイマー2. setTimeout() タイマーを停止する3. ...
目次1. オペレーティングシステムとは何か2. Linuxの起源3. Linuxの基本機能4. Li...
目次1. 開発環境2. dockerプラグインをインストールする1. アイデアのインストール2. イ...