ব্রাউজারটিকে একটি ড্রাগ এবং ড্রপ ফাইল লোড করা থেকে বিরত করুন


194

আমি আমার পৃষ্ঠায় এইচটিএমএল 5 ড্রাগ এবং ড্রপ আপলোডার যুক্ত করছি।

কোনও ফাইল যখন আপলোড অঞ্চলে ফেলে দেওয়া হয় তখন সবকিছু দুর্দান্ত কাজ করে।

যাইহোক, আমি যদি দুর্ঘটনাক্রমে ফাইলটি আপলোডের জায়গার বাইরে ফেলে দিই তবে ব্রাউজারটি স্থানীয় ফাইলটিকে লোড করে দেয় যেন এটি কোনও নতুন পৃষ্ঠা page

আমি কীভাবে এই আচরণটি আটকাতে পারি?

ধন্যবাদ!


2
এইচটিএমএল 5 ড্রাগ / ড্রপ আপলোড হ্যান্ডেল করতে আপনি কী কোডটি ব্যবহার করছেন তা কেবল কৌতুহল। ধন্যবাদ।
রবার্টব্রাবর্ডফোর্ড

আপনার সমস্যাটি হ'ল ই.ডাটা ট্রান্সফার () হারিয়ে যাওয়া বা ড্রপ / ড্রেজেটার / ইত্যাদিতে একটি প্রতিরোধ ডিফল্ট () হারিয়ে যাওয়ার কারণে। ইভেন্ট নেই। তবে আমি কোডের নমুনা ছাড়া বলতে পারি না।
হোল্ডঅফহাঙ্গার

উত্তর:


312

আপনি উইন্ডোতে ইভেন্ট শ্রোতা যুক্ত করতে পারেন যা preventDefault()সমস্ত ড্রাগগোভার এবং ড্রপ ইভেন্টগুলিতে কল করে।
উদাহরণ:

window.addEventListener("dragover",function(e){
  e = e || event;
  e.preventDefault();
},false);
window.addEventListener("drop",function(e){
  e = e || event;
  e.preventDefault();
},false);

44
ড্রাগগোভারটি সেই টুকরোটি ছিল যা আমি অনুপস্থিত ছিল।
cgatian

11
আমি নিশ্চিত হয়েছি যে ব্রাউজারটিকে বাদ পড়া ফাইলটি লোড করা থেকে বিরত রাখতে উভয় dragoverএবং dropহ্যান্ডলারের প্রয়োজন। (ক্রোম সর্বশেষ 2015/08/03)। সমাধানটি এফএফ সর্বশেষেও কাজ করে।
অফিরমো

4
এটি নিখুঁতভাবে কাজ করে এবং আমি নিশ্চিত করতে পারি যে এটি পৃষ্ঠা উপাদানগুলির সাথে মিশ্রণে ব্যবহার করা যেতে পারে যা ড্রপ ইভেন্টগুলি মেনে নেওয়ার জন্য কনফিগার করা হয়েছে, যেমন পুনরায় শুরুযোগ্য.জেসের মতো ড্রাগ-ড্রপ ফাইল আপলোড স্ক্রিপ্টগুলি। এটির ক্ষেত্রে ডিফল্ট ব্রাউজারের আচরণ রোধ করার জন্য দরকারী যখন কোনও ব্যবহারকারী দুর্ঘটনাক্রমে প্রকৃত ফাইল-আপলোড ড্রপ-জোনের বাইরে কোনও ফাইল আপলোড করতে চান এমন ফাইল ফেলে দেয় এবং তারপরে তারা কেন এখন সেই ফাইলটি সরাসরি ব্রাউজার উইন্ডোতে রেন্ডার করে তা অবাক করে দেয় ( তাদের ফাইল আপলোড দেখার প্রত্যাশিত আচরণের চেয়ে চিত্র বা ভিডিওর মতো উপযুক্ত ফাইলের ফাইলটি বাদ দেওয়া হয়েছিল) ধরে নেওয়া।
ব্লুবাইনারি

15
দ্রষ্টব্য: এটি একটিতে ফাইল টেনে আনতে অক্ষম করে <input type="file" />। এটি e.targetকোনও ফাইল ইনপুট কিনা তা খতিয়ে দেখা এবং এই জাতীয় ইভেন্টগুলি হওয়া উচিত।
সেবাস্তিয়ান নওক

6
কি ? উইন্ডো ড্র্যাগভার ফাইলটি লোড করবে কেন? এটি কোনও অর্থবহ নয় ...
এল.তাববাচিন

37

চারপাশে প্রচুর পরিশ্রমের পরেও আমি এটি স্থিতিশীল সমাধান হিসাবে পেয়েছি:

var dropzoneId = "dropzone";

window.addEventListener("dragenter", function(e) {
  if (e.target.id != dropzoneId) {
    e.preventDefault();
    e.dataTransfer.effectAllowed = "none";
    e.dataTransfer.dropEffect = "none";
  }
}, false);

window.addEventListener("dragover", function(e) {
  if (e.target.id != dropzoneId) {
    e.preventDefault();
    e.dataTransfer.effectAllowed = "none";
    e.dataTransfer.dropEffect = "none";
  }
});

window.addEventListener("drop", function(e) {
  if (e.target.id != dropzoneId) {
    e.preventDefault();
    e.dataTransfer.effectAllowed = "none";
    e.dataTransfer.dropEffect = "none";
  }
});
<div id="dropzone">...</div>

উভয় effectAllowএবং dropEffectবিনা শর্তে উইন্ডোতে সেট করার ফলে আমার ড্রপ জোনটি আর কোনও ডিএনডি গ্রহণ করবে না, বৈশিষ্ট্যগুলি নির্ধারিত হোক না কেন।


e.dataTransfer () এখানে এই সমালোচনামূলক অংশ যা এই কাজটি করে, যা "স্বীকৃত উত্তর" উল্লেখ করতে ব্যর্থ হয়েছিল।
হোল্ডঅফহাঙ্গার

9

JQuery এর জন্য সঠিক উত্তরটি হবে:

$(document).on({
    dragover: function() {
        return false;
    },
    drop: function() {
        return false;
    }
});

এখানে return falseহিসাবে event.preventDefault()এবং আচরণ করবে event.stopPropagation()


9

কিছু উপাদানগুলিতে কেবল ড্র্যাগ-এন্ড-ড্রপকে অনুমতি দেওয়ার জন্য আপনি এর মতো কিছু করতে পারেন:

window.addEventListener("dragover",function(e){
  e = e || event;
  console.log(e);
  if (e.target.tagName != "INPUT") { // check which element is our target
    e.preventDefault();
  }
},false);
window.addEventListener("drop",function(e){
  e = e || event;
  console.log(e);
  if (e.target.tagName != "INPUT") {  // check which element is our target
    e.preventDefault();
  }  
},false);

আমার জন্য নিখুঁত কাজ করে তবে আমি টাইপ = ফাইলের জন্য চেক যোগ করব, অন্যথায় আপনি এখনও পাঠ্য ইনপুটগুলিতে টেনে আনতে পারেন
Andreas Zwerger

2

এটা চেষ্টা কর:

document.body.addEventListener('drop', function(e) {
    e.preventDefault();
}, false);

2

ডিফল্টরূপে সমস্ত ড্রাগ এবং ড্রপ ক্রিয়াকলাপ রোধ করা আপনি যা চান তা নাও হতে পারে। কমপক্ষে কিছু ব্রাউজারে, ড্র্যাগ উত্স কোনও বাহ্যিক ফাইল কিনা তা পরীক্ষা করা সম্ভব। এই স্ট্যাকওভারফ্লো উত্তরের একটি ড্রাগ ফাইল কোনও বাহ্যিক ফাইল কিনা তা পরীক্ষা করতে আমি একটি ফাংশন অন্তর্ভুক্ত করেছি ।

ডিজিটাল প্লেনের উত্তরটি সংশোধন করে আপনি এরকম কিছু করতে পারেন:

function isDragSourceExternalFile() {
     // Defined here: 
     // https://stackoverflow.com/a/32044172/395461
}

window.addEventListener("dragover",function(e){
    e = e || event;
    var IsFile = isDragSourceExternalFile(e.originalEvent.dataTransfer);
    if (IsFile) e.preventDefault();
},false);
window.addEventListener("drop",function(e){
    e = e || event;
    var IsFile = isDragSourceExternalFile(e.originalEvent.dataTransfer);
    if (IsFile) e.preventDefault();
},false);

1
কিসের কথা e || event;? eventসংজ্ঞায়িত কোথায় ? কিছু মনে করো না. দেখে মনে হচ্ছে এটি আই-তে কোনও গ্লোবাল অবজেক্ট? আমি এই উদ্ধৃতিটি "In Microsoft Visual Basic Scripting Edition (VBScript), you must access the event object through the window object." এখানে
1.21 গিগাওয়াট

2

দ্রষ্টব্য: যদিও ওপি একটি কৌণিক সমাধানের জন্য জিজ্ঞাসা করে নি, আমি এটি খুঁজতে এখানে এসেছি। সুতরাং এটি যা আমি কার্যকর ব্যবহারযোগ্য সমাধান বলে মনে করি তা ভাগ করে নেওয়া, যদি আপনি কৌনিক ব্যবহার করেন।

আমার অভিজ্ঞতায় আপনি যখন কোনও পৃষ্ঠায় ফাইল ড্রপ কার্যকারিতা যুক্ত করেন তখন এই সমস্যাটি প্রথম দেখা দেয়। সুতরাং আমার মতামতটি হল যে উপাদানটি এটি যুক্ত করে তা ড্রপ জোনের বাইরে ড্রপ প্রতিরোধের জন্যও দায়ী।

আমার সমাধানে ড্রপ অঞ্চলটি একটি শ্রেণীর সাথে একটি ইনপুট, তবে যে কোনও দ্ব্যর্থহীন নির্বাচক কাজ করে।

import { Component, HostListener } from '@angular/core';
//...

@Component({
  template: `
    <form>
      <!-- ... -->
      <input type="file" class="dropzone" />
    </form>
  `
})
export class MyComponentWithDropTarget {

  //...

  @HostListener('document:dragover', ['$event'])
  @HostListener('drop', ['$event'])
  onDragDropFileVerifyZone(event) {
    if (event.target.matches('input.dropzone')) {
      // In drop zone. I don't want listeners later in event-chain to meddle in here
      event.stopPropagation();
    } else {
      // Outside of drop zone! Prevent default action, and do not show copy/move icon
      event.preventDefault();
      event.dataTransfer.effectAllowed = 'none';
      event.dataTransfer.dropEffect = 'none';
    }
  }
}

শ্রোতাগুলি উপাদান তৈরি / ধ্বংস হয়ে গেলে স্বয়ংক্রিয়ভাবে যুক্ত / সরানো হয় এবং একই পৃষ্ঠায় একই কৌশল ব্যবহার করে অন্যান্য উপাদানগুলি স্টপপ্রোগেশন () এর কারণে একে অপরের সাথে হস্তক্ষেপ করে না।


এটি একটি মোহন মত কাজ করে !! এমনকি ব্রাউজারটি নিষিদ্ধ আইকন যোগ করে মাউস কার্সার পরিবর্তন করে যা এত দুর্দান্ত !!
পিটিআই_জুল

1

অন্যান্য কয়েকটি উত্তরে বর্ণিত "লক্ষ্যটি পরীক্ষা করুন" পদ্ধতিটি তৈরি করার জন্য, এখানে আরও সাধারণ / কার্যকরী পদ্ধতি:

function preventDefaultExcept(predicates) {
  return function (e) {
    var passEvery = predicates.every(function (predicate) { return predicate(e); })
    if (!passEvery) {
      e.preventDefault();
    }
  };
}

যেমন বলা হয়:

function isDropzone(e) { return e.target.id === 'dropzone'; }
function isntParagraph(e) { return e.target.tagName !== 'p'; }

window.addEventListener(
  'dragover',
  preventDefaultExcept([isDropzone, isntParagraph])
);
window.addEventListener(
  'drop',
  preventDefaultExcept([isDropzone])
);

এছাড়াও, কিছু ES6 এখানে যোগ করতে পারিনি: function preventDefaultExcept(...predicates){}। এবং তারপরে এটি ব্যবহার করুনpreventDefaultExcept(isDropzone, isntParagraph)
hlfrmn

0

আমার একটি HTML object( embed) রয়েছে যা পৃষ্ঠার প্রস্থ এবং উচ্চতা পূরণ করে f @ ডিজিটাল-প্লেনের উত্তরটি সাধারণ ওয়েব পৃষ্ঠাগুলিতে কাজ করে তবে ব্যবহারকারী এম্বেড থাকা কোনও বস্তুর উপরে না যায়। সুতরাং আমার আলাদা সমাধান দরকার ছিল।

যদি আমরা ইভেন্ট ক্যাপচার পর্বটি ব্যবহার করতে স্যুইচ করি তবে এম্বেড হওয়া বস্তুটি তাদের গ্রহণের আগেই আমরা ইভেন্টগুলি পেতে পারি ( trueইভেন্ট শ্রোতার কলের শেষে মানটি লক্ষ্য করুন ):

// document.body or window
document.body.addEventListener("dragover", function(e){
  e = e || event;
  e.preventDefault();
  console.log("over true");
}, true);

document.body.addEventListener("drop", function(e){
  e = e || event;
  e.preventDefault();
  console.log("drop true");
}, true);

নিম্নলিখিত কোডটি ব্যবহার করা (@ ডিজিটাল-বিমানের উত্তরের উপর ভিত্তি করে) পৃষ্ঠাটি একটি টেনে আনার লক্ষ্য হিসাবে পরিণত হয়েছে, এটি ইভেন্টগুলি ক্যাপচারে অবজেক্ট এম্বেডগুলিকে বাধা দেয় এবং তারপরে আমাদের চিত্রগুলি লোড করে:

document.body.addEventListener("dragover", function(e){
  e = e || event;
  e.preventDefault();
  console.log("over true");
}, true);

document.body.addEventListener("drop",function(e){
  e = e || event;
  e.preventDefault();
  console.log("Drop true");

  // begin loading image data to pass to our embed
  var droppedFiles = e.dataTransfer.files;
  var fileReaders = {};
  var files = {};
  var reader;

  for (var i = 0; i < droppedFiles.length; i++) {
    files[i] = droppedFiles[i]; // bc file is ref is overwritten
    console.log("File: " + files[i].name + " " + files[i].size);
    reader = new FileReader();
    reader.file = files[i]; // bc loadend event has no file ref

    reader.addEventListener("loadend", function (ev, loadedFile) {
      var fileObject = {};
      var currentReader = ev.target;

      loadedFile = currentReader.file;
      console.log("File loaded:" + loadedFile.name);
      fileObject.dataURI = currentReader.result;
      fileObject.name = loadedFile.name;
      fileObject.type = loadedFile.type;
      // call function on embed and pass file object
    });

    reader.readAsDataURL(files[i]);
  }

}, true);

ম্যাকের ফায়ারফক্সে পরীক্ষিত।


0

আমি একাধিক আপলোড অঞ্চলের জন্য একটি শ্রেণি নির্বাচক ব্যবহার করছি তাই আমার সমাধানটি এটি কম খাঁটি ফর্ম নিয়েছে

অ্যাক্সেল অ্যামথরের উত্তরের উপর ভিত্তি করে, জিকুয়েরির উপর নির্ভরশীলতা (to এর সাথে সংযুক্ত)

_stopBrowserFromOpeningDragAndDropPDFFiles = function () {

        _preventDND = function(e) {
            if (!$(e.target).is($(_uploadBoxSelector))) {
                e.preventDefault();
                e.dataTransfer.effectAllowed = 'none';
                e.dataTransfer.dropEffect = 'none';
            }
        };

        window.addEventListener('dragenter', function (e) {
            _preventDND(e);
        }, false);

        window.addEventListener('dragover', function (e) {
            _preventDND(e);
        });

        window.addEventListener('drop', function (e) {
            _preventDND(e);
        });
    },
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.