この記事は主に、みんなで共有できる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 をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
今回は、私自身の開発経験を踏まえて、以下の観点で関連内容を解説します。ページからコンポーネントにデー...
概要プロジェクトは正常に作成され、正常にデプロイされましたが、以下に示すように、Tomcat サーバ...
概要: 2 つの MySQL SQL ステートメント ロックの分析次のSQL文にどのようなロックが追...
序文:ジュニアプログラマーとして、私は自分自身の個人ウェブサイトを構築し、それを他の人に見せることを...
雑談はここまでにして、インターネット上で見つかる高性能な Yahoo ウェブサイトを構築するための数...
1.まずAlibaba Cloudのウェブサイトにログインしてアカウントを登録し、サーバータイプを...
この記事では、例を使用して MySQL ビューの管理ビュー操作について説明します。ご参考までに、詳細...
ネットフィルターNetfilter は、パケット フィルタリング、転送、およびアドレス変換 NAT ...
mysql 8.0.11 winx64のインストールチュートリアルは以下のように記録され、みんなと...
知識ポイント1: ヘッダー情報にWebページのベースURLを設定するベース URL の本質は、ハイパ...
序文しばらく前にMysqlのデッドロック問題に遭遇したので、解決しました。問題の説明: Mysql ...
前回の記事では、Oracle でピボット テーブルを実装するいくつかの方法を紹介しました。今日は、同...
1. CSS3アニメーション☺CSS3 アニメーションは、JavaScript を介して要素のスタイ...
1》ウェブデザインが得意であること2》Webページのデザイン方法を知る3》計画する4. SEOを理解...
1. はじめにMySQL にログインすると、次のような警告が表示されることがよくあります。警告: コ...