फ़ाइल इनपुट पर रद्द किए जाने पर कैसे पता लगाएं?


112

जब उपयोगकर्ता HTML फ़ाइल इनपुट का उपयोग करके फ़ाइल इनपुट को रद्द करता है तो मैं कैसे पता लगा सकता हूं?

onChange मुझे यह पता लगाने देता है कि वे किसी फ़ाइल का चयन कब करते हैं, लेकिन मैं यह भी जानना चाहूंगा कि जब वे रद्द करते हैं (फ़ाइल का चयन डायलॉग को बिना कुछ चुने बिना बंद कर दें)।


आप यह भी पता लगा सकते हैं कि क्या कोई फ़ाइल e.target.files
उठाता है

जवाबों:


45

हालांकि एक सीधा समाधान नहीं है, और इसमें भी बुरा है कि यह केवल (जहां तक ​​मैंने परीक्षण किया है) ऑनफोकस के साथ काम करता है (एक बहुत सीमित घटना अवरुद्ध की आवश्यकता होती है) आप इसे निम्न के साथ प्राप्त कर सकते हैं:

document.body.onfocus = function(){ /*rock it*/ }

इसके बारे में क्या अच्छा है, यह है कि आप इसे फ़ाइल ईवेंट के साथ समय पर संलग्न / अलग कर सकते हैं, और यह छिपे हुए इनपुट के साथ भी ठीक काम करने लगता है (यदि आप भद्दा डिफ़ॉल्ट इनपुट प्रकार = के लिए एक दृश्य वर्कअराउंड का उपयोग कर रहे हैं, तो यह निश्चित है) फ़ाइल ')। उसके बाद, आपको बस यह पता लगाने की ज़रूरत है कि इनपुट मूल्य बदल गया है या नहीं।

एक उदाहरण:

var godzilla = document.getElementById('godzilla')

godzilla.onclick = charge

function charge()
{
    document.body.onfocus = roar
    console.log('chargin')
}

function roar()
{
    if(godzilla.value.length) alert('ROAR! FILES!')
    else alert('*empty wheeze*')
    document.body.onfocus = null
    console.log('depleted')
}

इसे क्रिया में देखें: http://jsfiddle.net/Shiboe/yuK3r/6/

अफसोस की बात है, यह केवल वेबकिट ब्राउज़र पर काम करने के लिए लगता है। हो सकता है कि कोई दूसरा व्यक्ति फ़ायरफ़ॉक्स / IE समाधान का पता लगा सके


मैं हर बार फायर इवेंट को फोकस नहीं करना चाहता था, इसलिए मैं उपयोग करना चाहता था addEventListener("focus",fn,{once: true})। हालाँकि, मैं इसका उपयोग करने के लिए आग में नहीं जा सका document.body.addEventListener.. मुझे पता नहीं क्यों। इसके बजाय मुझे वही परिणाम मिला window.addEventListener
वुडकिटीटी

3
यह मेरे लिए फ़ायरफ़ॉक्स और एज में काम नहीं करता है। हालांकि, के लिए सुन mousemoveपर घटना window.document अलावा सुनने की focusपर windowहर जगह (आधुनिक ब्राउज़रों में कम से कम, मैं पिछले दशक जहाजों के बारे में परवाह नहीं है) काम करने के लिए लगता है। मूल रूप से, इस कार्य के लिए किसी भी इंटरैक्शन इवेंट का उपयोग किया जा सकता है जो कि एक खुली फ़ाइल खुले संवाद द्वारा अवरुद्ध है।
जॉन वीज़

@WoodenKitty ने addEventListener का उपयोग करके इसे कैसे लागू किया। मैं कोणीय और दस्तावेज में ऐसा करने की कोशिश कर रहा हूं। कोई भी मेरे लिए काम नहीं कर रहा है
टेरेंस जैक्सन

यह छिपे हुए इनपुट फ़ील्ड पर काम नहीं करता है।
सेबेस्टियन

20

आप नहीं कर सकते।

फ़ाइल संवाद का परिणाम ब्राउज़र के संपर्क में नहीं है।


क्या यह जांचना संभव है कि फ़ाइल चयनकर्ता खुला है या नहीं?
Ppp

1
@Ppp - नहीं। ब्राउज़र आपको यह नहीं बताता है।
Oded

6
"फ़ाइल संवाद का परिणाम ब्राउज़र के संपर्क में नहीं है।" यदि फ़ाइल का चयन करके संवाद बंद हो जाता है तो यह सच नहीं है।
ट्रेवर

3
परिवर्तन फ़ाइल संवाद का उपयोग कर से शुरू हो रहा ब्राउज़र के संपर्क में है। देखें, यदि कोई फ़ाइल चयनित नहीं है, और बाद में कोई फ़ाइल चयनित नहीं है, तो कुछ भी नहीं बदला है, इस प्रकार कोई भी changeघटना नहीं भेजी जाती है।
जॉन वीज़

1
इसके अलावा, यदि कोई फ़ाइल पहले से ही चयनित है, और आप उसी फ़ाइल को फिर से चुनते हैं, changeतो उसके लिए कोई भी घटना नहीं भेजी जाती है।
पैट्रिक रॉबर्ट्स

16

इसलिए मैं इस सवाल पर अपनी टोपी फेंक दूंगा क्योंकि मैं एक उपन्यास समाधान के साथ आया था। मेरे पास एक प्रगतिशील वेब ऐप है जो उपयोगकर्ताओं को फ़ोटो और वीडियो कैप्चर करने और उन्हें अपलोड करने की अनुमति देता है। जब संभव हो तो हम WebRTC का उपयोग करते हैं, लेकिन कम समर्थन * खांसी सफारी खांसी * वाले उपकरणों के लिए HTML5 फ़ाइल पिकर पर वापस आते हैं। यदि आप विशेष रूप से एक एंड्रॉइड / आईओएस मोबाइल वेब एप्लिकेशन पर काम कर रहे हैं, जो सीधे फोटो / वीडियो कैप्चर करने के लिए देशी कैमरे का उपयोग करता है, तो यह सबसे अच्छा समाधान है जो मैं भर में आया हूं।

इस समस्या की जड़ यह है कि जब पृष्ठ लोड होता fileहै null, तो होता है , लेकिन तब जब उपयोगकर्ता संवाद खोलता है और "रद्द" करता है, तब fileभी होता है null, इसलिए यह "परिवर्तन" नहीं हुआ, इसलिए कोई "परिवर्तन" घटना ट्रिगर नहीं होती है। डेस्कटॉप के लिए, यह बहुत बुरा नहीं है क्योंकि अधिकांश डेस्कटॉप यूआई रद्द किए जाने पर जानने पर निर्भर नहीं होते हैं, लेकिन मोबाइल यूआई के जो एक तस्वीर / वीडियो को कैप्चर करने के लिए कैमरा लाते हैं, यह जानने पर बहुत निर्भर करते हैं कि कैंसल कब दबाया जाता है।

मैंने मूल रूप से document.body.onfocusघटना का पता लगाने के लिए उपयोग किया जब उपयोगकर्ता फ़ाइल पिकर से लौटा, और इसने अधिकांश उपकरणों के लिए काम किया, लेकिन iOS 11.3 ने इसे तोड़ दिया क्योंकि यह घटना ट्रिगर नहीं है।

संकल्पना

इसका समाधान सीपीयू टाइमिंग को मापने के लिए * कंपकंपी * है यह निर्धारित करने के लिए कि पृष्ठ वर्तमान में अग्रभूमि या पृष्ठभूमि में है। मोबाइल उपकरणों पर, अग्रभूमि में वर्तमान में एप्लिकेशन को प्रसंस्करण समय दिया जाता है। जब एक कैमरा दिखाई देता है तो यह सीपीयू समय चुराएगा और ब्राउज़र को चित्रित करेगा। हमें केवल यह मापने की आवश्यकता है कि हमारे पेज को कितना प्रसंस्करण समय दिया जाता है, जब कैमरा लॉन्च करता है तो हमारा उपलब्ध समय काफी कम हो जाएगा। जब कैमरा खारिज कर दिया जाता है (या तो रद्द कर दिया जाता है या अन्यथा), हमारा उपलब्ध समय स्पाइक बैक अप होता है।

कार्यान्वयन

हम setTimeout()एक्स मिलीसेकंड में एक कॉलबैक आह्वान करके CPU समय को माप सकते हैं , और फिर माप सकते हैं कि वास्तव में इसे लागू करने में कितना समय लगा। ब्राउज़र यह आह्वान कभी नहीं होगा वास्तव में एक्स मिलीसेकेंड के बाद, लेकिन अगर यह उचित करीब है तो हम अग्रभूमि में होना चाहिए। यदि ब्राउज़र बहुत दूर है (अनुरोध के मुकाबले 10x से अधिक धीमा) तो हमें पृष्ठभूमि में होना चाहिए। इसका एक बुनियादी कार्यान्वयन ऐसा है:

function waitForCameraDismiss() {
  const REQUESTED_DELAY_MS = 25;
  const ALLOWED_MARGIN_OF_ERROR_MS = 25;
  const MAX_REASONABLE_DELAY_MS =
      REQUESTED_DELAY_MS + ALLOWED_MARGIN_OF_ERROR_MS;
  const MAX_TRIALS_TO_RECORD = 10;

  const triggerDelays = [];
  let lastTriggerTime = Date.now();

  return new Promise((resolve) => {
    const evtTimer = () => {
      // Add the time since the last run
      const now = Date.now();
      triggerDelays.push(now - lastTriggerTime);
      lastTriggerTime = now;

      // Wait until we have enough trials before interpreting them.
      if (triggerDelays.length < MAX_TRIALS_TO_RECORD) {
        window.setTimeout(evtTimer, REQUESTED_DELAY_MS);
        return;
      }

      // Only maintain the last few event delays as trials so as not
      // to penalize a long time in the camera and to avoid exploding
      // memory.
      if (triggerDelays.length > MAX_TRIALS_TO_RECORD) {
        triggerDelays.shift();
      }

      // Compute the average of all trials. If it is outside the
      // acceptable margin of error, then the user must have the
      // camera open. If it is within the margin of error, then the
      // user must have dismissed the camera and returned to the page.
      const averageDelay =
          triggerDelays.reduce((l, r) => l + r) / triggerDelays.length
      if (averageDelay < MAX_REASONABLE_DELAY_MS) {
        // Beyond any reasonable doubt, the user has returned from the
        // camera
        resolve();
      } else {
        // Probably not returned from camera, run another trial.
        window.setTimeout(evtTimer, REQUESTED_DELAY_MS);
      }
    };
    window.setTimeout(evtTimer, REQUESTED_DELAY_MS);
  });
}

मैंने आईओएस और एंड्रॉइड के हाल के संस्करण पर इसका परीक्षण किया, <input />तत्व पर विशेषताओं को सेट करके देशी कैमरा को ऊपर लाया ।

<input type="file" accept="image/*" capture="camera" />
<input type="file" accept="video/*" capture="camcorder" />

यह वास्तव में मेरी उम्मीद से बेहतर काम करता है। 25 मिलीसेकंड में एक टाइमर लगाने का अनुरोध करके यह 10 परीक्षण करता है। यह तब मापता है कि वास्तव में इसे लागू करने में कितना समय लगा, और यदि 10 परीक्षणों का औसत 50 मिलीसेकंड से कम है, तो हम मानते हैं कि हमें अग्रभूमि में होना चाहिए और कैमरा चला गया है। यदि यह 50 मिलीसेकंड से अधिक है, तो हमें अभी भी पृष्ठभूमि में होना चाहिए और इंतजार करना जारी रखना चाहिए।

कुछ अतिरिक्त विवरण

मैंने इसके setTimeout()बजाय इसका उपयोग किया setInterval()क्योंकि उत्तरार्द्ध कई आक्रमणों को पंक्तिबद्ध कर सकता है जो एक दूसरे के तुरंत बाद निष्पादित होते हैं। यह हमारे डेटा में शोर को काफी बढ़ा सकता है, इसलिए मैं setTimeout()ऐसा करने के लिए थोड़ा और अधिक जटिल होने के बावजूद अटक गया ।

इन विशेष नंबरों ने मेरे लिए अच्छा काम किया, हालांकि मैंने कम से कम एक बार उदाहरण देखा है जहां समय से पहले कैमरे को खारिज कर दिया गया था। मेरा मानना ​​है कि ऐसा इसलिए है क्योंकि कैमरा खोलने में धीमा हो सकता है, और डिवाइस वास्तव में पृष्ठभूमि बनने से पहले 10 परीक्षण चला सकता है। इस कार्य को शुरू करने से पहले अधिक से अधिक परीक्षणों को जोड़ना या कुछ 25-50 मिलीसेकंड की प्रतीक्षा करना इसके लिए एक समाधान हो सकता है।

डेस्कटॉप

दुर्भाग्य से, यह वास्तव में डेस्कटॉप ब्राउज़रों के लिए काम नहीं करता है। सिद्धांत रूप में एक ही चाल संभव है क्योंकि वे पृष्ठभूमि वाले पृष्ठों पर वर्तमान पृष्ठ को प्राथमिकता देते हैं। हालाँकि कई डेस्कटॉप के पास पर्याप्त संसाधन होते हैं जो पृष्ठ को पृष्ठभूमि में रखते हुए भी पूरी गति से चलते रहते हैं, इसलिए यह रणनीति वास्तव में काम नहीं करती है।

वैकल्पिक समाधान

एक वैकल्पिक समाधान में कई लोगों का उल्लेख नहीं है कि मैंने जो खोज की थी वह मजाक उड़ा रहा था FileList। हम इसके साथ शुरू nullकरते हैं <input />और फिर यदि उपयोगकर्ता कैमरा और रद्द करता है तो वे वापस आ जाते हैं null, जो कि परिवर्तन नहीं है और कोई भी घटना ट्रिगर नहीं होगी। एक समाधान <input />पृष्ठ प्रारंभ में एक डमी फ़ाइल को असाइन करना होगा , इसलिए सेटिंग में nullएक परिवर्तन होगा जो उचित घटना को ट्रिगर करेगा।

दुर्भाग्य से, कोई रास्ता नहीं है आधिकारिक तौर पर एक बनाने के लिए FileList, और <input />तत्व को FileListविशेष रूप से आवश्यकता होती है और इसके अलावा किसी भी अन्य मूल्य को स्वीकार नहीं करेगा null। स्वाभाविक रूप से, FileListवस्तुओं का निर्माण सीधे नहीं किया जा सकता है, कुछ पुराने सुरक्षा मुद्दे पर करें जो अब तक स्पष्ट रूप से प्रासंगिक नहीं हैं। एक <input />तत्व के बाहर एक का एक हिस्सा पाने का एकमात्र तरीका एक हैक का उपयोग करना है जो एक क्लिपबोर्ड घटना को कॉपी करने के लिए डेटा को कॉपी-पेस्ट करता है जिसमें FileListऑब्जेक्ट हो सकता है (आप मूल रूप से ड्रैग-एंड-ड्रॉप-ए-फाइल-ऑन को फेक कर रहे हैं -आपकी वेबसाइट घटना)। फ़ायरफ़ॉक्स में यह संभव है, लेकिन आईओएस सफारी के लिए नहीं, इसलिए यह मेरे विशेष उपयोग के मामले में व्यवहार्य नहीं था।

ब्राउज़रों, कृपया ...

यह कहने की आवश्यकता नहीं है कि यह हास्यास्पद है। तथ्य यह है कि वेब पृष्ठों को शून्य सूचना दी जाती है कि एक महत्वपूर्ण यूआई तत्व बदल गया है, बस हँसने योग्य है। यह वास्तव में कल्पना में एक बग है, क्योंकि यह कभी भी पूर्ण-स्क्रीन मीडिया कैप्चर यूआई के लिए नहीं था, और "परिवर्तन" घटना को ट्रिगर करने के लिए तकनीकी रूप से कल्पना नहीं है।

हालांकि , क्या ब्राउज़र विक्रेता कृपया इसकी वास्तविकता को पहचान सकते हैं? इसे किसी नए "किए गए" ईवेंट के साथ हल किया जा सकता है जो तब भी ट्रिगर होता है जब कोई परिवर्तन नहीं होता है, या आप "परिवर्तन" को किसी भी तरह से ट्रिगर कर सकते हैं। हाँ, यह कल्पना के खिलाफ होगा, लेकिन मेरे लिए जावास्क्रिप्ट की ओर एक परिवर्तन घटना को कम करने के लिए यह तुच्छ है, फिर भी मौलिक रूप से अपने स्वयं के "किए गए" घटना का आविष्कार करना असंभव है। यहां तक ​​कि मेरा समाधान वास्तव में सिर्फ आंकड़े हैं, अगर ब्राउज़र की स्थिति पर कोई गारंटी नहीं देता है।

जैसा कि यह खड़ा है, यह एपीआई मोबाइल उपकरणों के लिए मौलिक रूप से अनुपयोगी है, और मुझे लगता है कि अपेक्षाकृत सरल ब्राउज़र परिवर्तन वेब डेवलपर्स के लिए असीम रूप से आसान बना सकता है * साबुन बॉक्स * से कदम।



7

जब आप किसी फ़ाइल का चयन करते हैं और खुले / रद्द करते हैं, तो inputतत्व को फोकस उर्फ ​​खोना चाहिए blur। प्रारंभिक valueके मान लेने inputसे खाली है, आपके blurहैंडलर में कोई भी खाली मूल्य ठीक है, और रिक्त मान का अर्थ रद्द करना होगा।

अद्यतन: blurजब inputछिपा हुआ है ट्रिगर नहीं है। इसलिए IFRAME- आधारित अपलोड के साथ इस ट्रिक का उपयोग नहीं कर सकते, जब तक कि आप अस्थायी रूप से प्रदर्शित नहीं करना चाहते input


3
फ़ायरफ़ॉक्स 10 बीटा और क्रोम 16 में, blurजब आप किसी फ़ाइल का चयन करते हैं तो ट्रिगर नहीं होता है। अन्य ब्राउज़र में आज़माया नहीं गया है।
ब्लेस

1
यह काम नहीं करता है - क्लिक करने के तुरंत बाद इनपुट पर धब्बा चालू हो जाता है। Win7 पर क्रोम 63.0.3239.84 x64।
Qwertiy

7
/* Tested on Google Chrome */
$("input[type=file]").bind("change", function() {
    var selected_file_name = $(this).val();
    if ( selected_file_name.length > 0 ) {
        /* Some file selected */
    }
    else {
        /* No file selected or cancel/close
           dialog button clicked */
        /* If user has select a file before,
           when they submit, it will treated as
           no file selected */
    }
});

6
यदि आपने elseकभी अपने कथन का मूल्यांकन किया है तो क्या आपने जाँच की है ?
जयरजो

जहाँ तक मुझे याद है जब मैंने यह उत्तर लिखा था, यदि उपयोगकर्ता एक फ़ाइल का चयन करता है और फिर फ़ाइल का चयन करता है (लेकिन फिर रद्द कर रहा है), तो इसे कोई फ़ाइल चयनित नहीं माना जाएगा, मैं केवल इसे परीक्षण करने के लिए चयनित_file_name चर पर अलर्ट का उपयोग करता हूं। वैसे भी, तब से अब तक इसका परीक्षण नहीं किया है।
रिज़की

4
मैं कह सकता हूं, कुछ क्रॉस ब्राउजर परीक्षण के बाद, कि फ़ायरफ़ॉक्स रद्द करने पर एक परिवर्तन की घटना को आग नहीं देता है, और न ही मौजूदा फ़ाइलों को फिर से खोलने और रद्द किए जाने पर चयनित फ़ाइलों को साफ़ नहीं करता है। अजीब बात है, एह?
मिश्रण

7

इनमें से अधिकांश समाधान मेरे लिए काम नहीं करते हैं।

समस्या यह है कि आपको कभी नहीं पता होगा कि कौन सी घटना मुट्ठी में होगी, यह है clickया यह है change? आप किसी भी आदेश को नहीं मान सकते, क्योंकि यह संभवतः ब्राउज़र के कार्यान्वयन पर निर्भर करता है।

कम से कम ओपेरा और क्रोम (2015 के अंत में) clickफाइलों के साथ 'भरने' के इनपुट से ठीक पहले चालू हो जाता है, इसलिए आपको कभी भी इसकी लंबाई का पता नहीं चलेगा कि files.length != 0आप इसके clickबाद ट्रिगर होने में देरी करते हैं change

यहाँ कोड है:

var inputfile = $("#yourid");

inputfile.on("change click", function(ev){
    if (ev.originalEvent != null){
        console.log("OK clicked");
    }
    document.body.onfocus = function(){
        document.body.onfocus = null;
        setTimeout(function(){
            if (inputfile.val().length === 0) console.log("Cancel clicked");
        }, 1000);
    };
});

यदि आप पृष्ठ पर क्लिक करते हैं ... "रद्द करें क्लिक करें" ... = | (क्रोम के साथ परीक्षण किया गया)
एडुआर्डो लुसियो

5

बस क्लिक इवेंट को भी सुनें।

शिबो के उदाहरण से, यहाँ एक jQuery का उदाहरण दिया गया है:

var godzilla = $('#godzilla');
var godzillaBtn = $('#godzilla-btn');

godzillaBtn.on('click', function(){
    godzilla.trigger('click');
});

godzilla.on('change click', function(){

    if (godzilla.val() != '') {
        $('#state').html('You have chosen a Mech!');    
    } else {
        $('#state').html('Choose your Mech!');
    }

});

आप इसे यहां एक्शन में देख सकते हैं: http://jsfiddle.net/T3Vwz


1
मैंने Chrome 51 पर परीक्षण किया, यह पहली बार आपके द्वारा फ़ाइलों का चयन करने पर काम नहीं करता है। विलम्ब से जोड़ने का उपाय है: jsfiddle.net/7jfbmunh
बेनोइट ब्लैंचॉन

आपके फिडल ने मेरे लिए काम नहीं किया - फायरफॉक्स 58.0.2
बैरीपिकर

4

यदि आप पहले जैसी फ़ाइल चुनते हैं और आप रद्द करते हैं: तो आप इस मामले में रद्द कर सकते हैं।

आप इसे इस तरह से कर सकते हैं:

<input type="file" id="myinputfile"/>
<script>
document.getElementById('myinputfile').addEventListener('change', myMethod, false);
function myMethod(evt) {
  var files = evt.target.files; 
  f= files[0];
  if (f==undefined) {
     // the user has clicked on cancel
  }
  else if (f.name.match(".*\.jpg")|| f.name.match(".*\.png")) {
     //.... the user has choosen an image file
     var reader = new FileReader();
     reader.onload = function(evt) { 
        try {
        myimage.src=evt.target.result;
            ...
         } catch (err) {
            ...
         }
     };
  }     
  reader.readAsDataURL(f);          
</script>

1
Thnkx @loveJs इस पोस्ट ने वास्तव में मेरी मदद की।
वीपीके

4
ठीक नहीं, अगर उपयोगकर्ता उसी फ़ाइल का चयन करता है जो कि रद्द नहीं है = (
टियागो पेरेस फ़्राँसा

13
यदि परिवर्तन हुआ था, तो onchange केवल आग लगाता है। तो अगर फ़ाइल पिछले फ़ाइल के रूप में एक ही फाइल है, तो श्रोता आग नहीं लगाएगा।
शेन

1
पहली बार परिवर्तन का पता लगाने के बाद आप इनपुट चयन (input.value = '') को साफ कर सकते हैं, ताकि दूसरी बार ऑनकॉन्ग में आग लग जाए, भले ही उपयोगकर्ता फिर से उसी फ़ाइल का चयन करे।
क्रिस

1
@CodeGems यह प्रोग्राम को इनपुट करने के लिए अनुमति देता है। खाली स्ट्रिंग के लिए। लेकिन आप सही हैं कि इसे किसी अन्य मूल्य पर सेट करने की अनुमति नहीं है।
क्रिस

4

सबसे आसान तरीका यह है कि अस्थायी मेमोरी में कोई फाइल है या नहीं इसकी जांच करें। यदि आप हर बार उपयोगकर्ता को उस परिवर्तन ईवेंट को प्राप्त करना चाहते हैं जो फ़ाइल इनपुट पर क्लिक करता है तो आप उसे ट्रिगर कर सकते हैं।

var yourFileInput = $("#yourFileInput");

yourFileInput.on('mouseup', function() {
    $(this).trigger("change");
}).on('change', function() {
    if (this.files.length) {
        //User chose a picture
    } else {
        //User clicked cancel
    }
});

2

अगर यह मोबाइल वेबकिट पर काम करता है, तो शिबो का समाधान एक अच्छा होगा, लेकिन यह नहीं है। मैं उस समय किसी डोम ऑब्जेक्ट में एक मूसमोव ईवेंट श्रोता को जोड़ने के लिए आ सकता हूं जो फ़ाइल इनपुट विंडो खोली जाती है, जैसे:

 $('.upload-progress').mousemove(function() {
        checkForFiles(this);
      });
      checkForFiles = function(me) {
        var filefield = $('#myfileinput');
        var files = filefield.get(0).files;
        if (files == undefined || files[0] == undefined) $(me).remove(); // user cancelled the upload
      };

फ़ाइल डायलॉग खुला रहने पर मूसमव ईवेंट को पृष्ठ से ब्लॉक कर दिया जाता है, और जब उसका बंद होना यह देखना होता है कि फ़ाइल इनपुट में कोई फाइल है या नहीं। मेरे मामले में मैं फ़ाइल को अपलोड किए जाने तक चीजों को अवरुद्ध करने वाला एक गतिविधि संकेतक चाहता हूं, इसलिए मैं केवल रद्द करने पर अपना संकेतक निकालना चाहता हूं।

हालाँकि, यह मोबाइल के लिए हल नहीं करता है, क्योंकि मूव करने के लिए कोई माउस नहीं है। मेरा समाधान सही से कम है, लेकिन मुझे लगता है कि यह काफी अच्छा है।

       $('.upload-progress').bind('touchstart', function() {
        checkForFiles(this);
      });

अब हम स्क्रीन पर एक स्पर्श के लिए सुन रहे हैं कि वही फाइलें चेक करें। मुझे पूरा विश्वास है कि इस गतिविधि संकेतक को रद्द करने और खारिज करने के बाद उपयोगकर्ता की उंगली बहुत जल्दी स्क्रीन पर डाल दी जाएगी।

कोई व्यक्ति फ़ाइल इनपुट परिवर्तन घटना पर केवल गतिविधि संकेतक जोड़ सकता है, लेकिन मोबाइल पर अक्सर छवि और परिवर्तन घटना फायरिंग का चयन करने के बीच कुछ सेकंड का अंतराल होता है, इसलिए गतिविधि सूचक को प्रदर्शित करने के लिए इसका सिर्फ बेहतर UX है प्रक्रिया की शुरुआत।


2

मुझे यह सबसे अच्छा लगता है।

if ($('#selectedFile')[0].files.length > 1)
{
   // Clicked on 'open' with file
} else {
   // Clicked on 'cancel'
}

यहाँ, selectedFileएक है input type=file


यह मेरे लिए एक अच्छा समाधान है, सिवाय इसके कि यह 1 = 1
ब्रॉन थुलके

2

मुझे पता है कि यह एक बहुत पुराना सवाल है, लेकिन अगर किसी को रद्द करने का पता लगाने के लिए onmousemove घटना का उपयोग करते समय मैंने पाया है कि बस समय की थोड़ी सी जगह में दो या अधिक ऐसी घटनाओं के लिए परीक्षण करना आवश्यक था। ऐसा इसलिए था क्योंकि हर बार ब्राउज़र (क्रोम 65) द्वारा सिंगल ऑनसमूव इवेंट्स उत्पन्न किए जाते हैं, हर बार कर्सर को चुनिंदा फ़ाइल डायलॉग विंडो से बाहर ले जाया जाता है और हर बार इसे मुख्य विंडो से बाहर ले जाया जाता है और माउस मूवमेंट इवेंट का एक सरल काउंटर होता है। काउंटर को शून्य पर वापस सेट करने के लिए एक छोटी अवधि के समय के साथ युग्मित किया गया एक उपचार का काम करता है।


1
पहला पैराग्राफ एक अच्छा उत्तर है, भले ही इसे बेहतर पठनीयता के लिए कई में विभाजित किया जा सकता है। लेकिन वे दो "SOAPBOX" लाइनें इसे एक गैर-उत्तर के लिए सीमा रेखा बनाती हैं क्योंकि प्रश्न उत्तर में नहीं होते हैं। क्या आप अपने उत्तर को थोड़ा सा वापस कर सकते हैं? धन्यवाद।
फिल्नोर

1

मेरे मामले में मुझे सबमिट बटन को छिपाना पड़ा जबकि उपयोगकर्ता छवियों का चयन कर रहे थे।

यह मैं आ रहा हूँ:

$(document).on('click', '#image-field', function(e) {
  $('.submit-button').prop('disabled', true)
})
$(document).on('focus', '#image-field'), function(e) {
  $('.submit-button').prop('disabled', false)
})

#image-fieldमेरी फ़ाइल चयनकर्ता है जब somenone उस पर क्लिक करता है, तो मैं फ़ॉर्म सबमिट बटन अक्षम करता हूं। बिंदु यह है, जब फ़ाइल संवाद बंद हो जाता है - कोई फर्क नहीं पड़ता कि वे एक फ़ाइल का चयन करते हैं या रद्द करते हैं - #image-fieldफोकस वापस मिल गया, इसलिए मैं उस घटना को सुनता हूं।

अपडेट करें

मैंने पाया कि, यह सफारी और पॉलीटेजिस्ट / फैंटमज में काम नहीं करता है। यदि आप इसे लागू करना चाहते हैं तो इस जानकारी को ध्यान में रखें।


1

शिबो और एल्क्स के समाधानों को मिलाकर, मुझे सबसे विश्वसनीय कोड मिला है:

var selector = $('<input/>')
   .attr({ /* just for example, use your own attributes */
      "id": "FilesSelector",
      "name": "File",
      "type": "file",
      "contentEditable": "false" /* if you "click" on input via label, this prevents IE7-8 from just setting caret into file input's text filed*/
   })
   .on("click.filesSelector", function () {
      /* do some magic here, e.g. invoke callback for selection begin */
      var cancelled = false; /* need this because .one calls handler once for each event type */
      setTimeout(function () {
         $(document).one("mousemove.filesSelector focusin.filesSelector", function () {
            /* namespace is optional */
            if (selector.val().length === 0 && !cancelled) {
               cancelled = true; /* prevent double cancel */
               /* that's the point of cancel,   */
            }
         });                    
      }, 1); /* 1 is enough as we just need to delay until first available tick */
   })
   .on("change.filesSelector", function () {
      /* do some magic here, e.g. invoke callback for successful selection */
   })
   .appendTo(yourHolder).end(); /* just for example */

आम तौर पर, मूसमोव ईवेंट चाल करता है, लेकिन मामले में उपयोगकर्ता ने एक क्लिक और किया:

  • भागने की कुंजी (माउस को हिलाए बिना) द्वारा फ़ाइल खुला संवाद रद्द कर दिया, फिर से फ़ाइल संवाद खोलने के लिए एक और सटीक क्लिक किया ...
  • किसी भी अन्य अनुप्रयोग पर ध्यान केंद्रित किया, ब्राउज़र की फ़ाइल के खुले संवाद पर वापस आने और इसे बंद करने की तुलना में, दर्ज या अंतरिक्ष कुंजी के माध्यम से फिर से खोला ...

... हमें मूसमव इवेंट नहीं मिलेगा इसलिए कोई कॉलबैक रद्द नहीं होगा। इसके अलावा, यदि उपयोगकर्ता दूसरा डायलॉग रद्द करता है और माउस ले जाता है, तो हमें 2 रद्द कॉलबैक मिलेंगे। सौभाग्य से, विशेष jQuery का ध्यान केंद्रित। घटना दोनों स्थितियों में दस्तावेज़ में बुलबुले बनती है, जिससे हमें ऐसी स्थितियों से बचने में मदद मिलती है। केवल एक ही सीमा है अगर एक भी ध्यान केंद्रित करता है।


मैंने Ubuntu 16.10 को क्रोम 56.0.2924.87 में ओएस संवाद में फ़ाइलों का चयन करने के दौरान mousemoveघटना को पकड़ा document। कोई समस्या नहीं है, जब माउस नहीं बढ़ रहा है, या फ़ाइल का चयन करने के लिए सिर्फ कीबोर्ड का उपयोग कर रहा है। मैं बदलने के लिए था mousemoveद्वारा keydownयथाशीघ्र रद्द पता लगाने के लिए, लेकिन "बहुत जल्दी", जब संवाद अभी भी खुला था।
फर्डिनेंड प्रांटल

1

मैं देखता हूं कि मेरी प्रतिक्रिया काफी पुरानी होगी, लेकिन कभी कम नहीं हुई। मैंने उसी समस्या का सामना किया। तो यहाँ मेरा समाधान है। सबसे उपयोगी कोड छीन लिया गया था केजीए का। लेकिन यह पूरी तरह से काम नहीं कर रहा है और थोड़ा जटिल है। लेकिन मैंने इसे सरल बनाया।

इसके अलावा, मुख्य परेशानी निर्माता तथ्य यह था, कि 'परिवर्तन' घटना फ़ोकस के तुरंत बाद नहीं आती है, इसलिए हमें कुछ समय तक इंतजार करना होगा।

"#appendfile" - जो उपयोगकर्ता एक नई फ़ाइल को जोड़ने के लिए क्लिक करता है। Hrefs को फोकस इवेंट मिलते हैं।

$("#appendfile").one("focusin", function () {
    // no matter - user uploaded file or canceled,
    // appendfile gets focus
    // change doesn't come instantly after focus, so we have to wait for some time
    // wrapper represents an element where a new file input is placed into
    setTimeout(function(){
        if (wrapper.find("input.fileinput").val() != "") {
            // user has uploaded some file
            // add your logic for new file here
        }
        else {
            // user canceled file upload
            // you have to remove a fileinput element from DOM
        }
    }, 900);
});

1

इसका पता आप सीमित परिस्थितियों में ही लगा सकते हैं। विशेष रूप से, क्रोम में यदि किसी फ़ाइल को पहले चुना गया था और फिर फ़ाइल संवाद पर क्लिक किया गया और रद्द किया गया क्लिक किया गया है, तो क्रोम फ़ाइल को साफ़ करता है और ऑनकॉन्ग इवेंट को फायर करता है।

https://code.google.com/p/chromium/issues/detail?id=2508

इस परिदृश्य में, आप onChange ईवेंट को हैंडल करके और फ़ाइलों की संपत्ति की जाँच करके इसका पता लगा सकते हैं।


1

निम्नलिखित मेरे लिए काम करने लगता है (डेस्कटॉप, विंडोज़ पर):

var openFile = function (mimeType, fileExtension) {
    var defer = $q.defer();
    var uploadInput = document.createElement("input");
    uploadInput.type = 'file';
    uploadInput.accept = '.' + fileExtension + ',' + mimeType;

    var hasActivated = false;

    var hasChangedBeenCalled = false;
    var hasFocusBeenCalled = false;
    var focusCallback = function () {
        if (hasActivated) {
            hasFocusBeenCalled = true;
            document.removeEventListener('focus', focusCallback, true);
            setTimeout(function () {
                if (!hasChangedBeenCalled) {
                    uploadInput.removeEventListener('change', changedCallback, true);
                    defer.resolve(null);
                }
            }, 300);
        }
    };

    var changedCallback = function () {
        uploadInput.removeEventListener('change', changedCallback, true);
        if (!hasFocusBeenCalled) {
            document.removeEventListener('focus', focusCallback, true);
        }
        hasChangedBeenCalled = true;
        if (uploadInput.files.length === 1) {
            //File picked
            var reader = new FileReader();
            reader.onload = function (e) {
                defer.resolve(e.target.result);
            };
            reader.readAsText(uploadInput.files[0]);
        }
        else {
            defer.resolve(null);
        }
    };
    document.addEventListener('focus', focusCallback, true); //Detect cancel
    uploadInput.addEventListener('change', changedCallback, true); //Detect when a file is picked
    uploadInput.click();
    hasActivated = true;
    return defer.promise;
}

यह angularjs $ q का उपयोग करता है, लेकिन आपको जरूरत पड़ने पर इसे किसी अन्य वादे के ढांचे के साथ बदलने में सक्षम होना चाहिए।

IE11, एज, क्रोम, फायरफॉक्स पर परीक्षण किया गया है, लेकिन यह एंड्रॉइड टैबलेट पर क्रोम पर काम नहीं करता है क्योंकि यह फोकस इवेंट को फायर नहीं करता है।


1

fileप्रकार क्षेत्र, frustratingly, (कलंक सुंदर होगा) की घटनाओं का एक बहुत का जवाब नहीं है। मैं बहुत से लोगों को सलाह देता हूं कि वे changeसमाधानों का सुझाव दे रहे हैं और उन्हें कम किया जा रहा है।

changeकाम करता है, लेकिन इसका एक बड़ा दोष है (बनाम हम जो होना चाहते हैं)।

जब आप किसी फ़ाइल फ़ील्ड में नए सिरे से लोड करते हैं, तो बॉक्स खोलें और रद्द करें दबाएं। कुछ भी नहीं, निराशा से, बदलता है

मैंने जो करने के लिए चुना है वह एक gated-state में लोड है।

  • section#after-imageमेरे मामले में प्रपत्र का अगला भाग दृश्य से छिपा हुआ है। जब मेरा file fieldपरिवर्तन होता है, तो एक अपलोड बटन दिखाया जाता है। सफल अपलोड पर, section#after-imageदिखाया गया है।
  • यदि उपयोगकर्ता लोड करता है, फ़ाइल-डायलॉग खोलता है, तो रद्द कर देता है, वे अपलोड बटन कभी नहीं देखते हैं।
  • यदि उपयोगकर्ता कोई फ़ाइल चुनता है, तो अपलोड बटन दिखाया जाता है। यदि वे फिर संवाद खोलते हैं और रद्द करते हैं, तो changeइस रद्द करने से ईवेंट चालू हो जाता है, और वहां मैं अपने अपलोड बटन को फिर से छिपा सकता हूं जब तक कि एक उचित फ़ाइल का चयन नहीं किया जाता है।

मैं भाग्यशाली था कि यह गेट-स्टेट पहले से ही मेरे फॉर्म का डिज़ाइन था। आपको एक ही शैली का उपयोग करने की आवश्यकता नहीं है, केवल अपलोड बटन शुरू में छिपा हुआ है और बदलने पर, एक छिपे हुए क्षेत्र या जावास्क्रिप्ट चर को कुछ पर सेट करना है जिसे आप सबमिट कर सकते हैं।

मैंने फ़ील्ड के साथ बातचीत करने से पहले फ़ाइलों का मान बदलने की कोशिश की [0]। इसने onchange के बारे में कुछ नहीं किया।

हां, changeकाम करता है, कम से कम जितना हम प्राप्त करने जा रहे हैं उतना अच्छा है। फ़ाइलफ़ील्ड स्पष्ट कारणों से सुरक्षित है, लेकिन अच्छी तरह से इरादे वाले डेवलपर्स की निराशा के लिए।

यह मेरे उद्देश्य के लिए उपयुक्त नहीं है, लेकिन आप onclickचेतावनी प्रॉम्प्ट को लोड करने में सक्षम हो सकते हैं (नहीं alert(), क्योंकि पृष्ठ-प्रसंस्करण को रोकता है), और इसे छिपाएं यदि परिवर्तन ट्रिगर हो गया है और फाइलें [0] शून्य है। यदि परिवर्तन को ट्रिगर नहीं किया जाता है, तो div अपने राज्य में रहता है।


0

ऐसा करने के लिए एक हैक तरीका है ( alert()कॉल के बजाय कॉलबैक जोड़ें या कुछ स्थगित / वादा कार्यान्वयन का समाधान करें ):

var result = null;

$('<input type="file" />')
    .on('change', function () {
        result = this.files[0];
        alert('selected!');
    })
    .click();

setTimeout(function () {
    $(document).one('mousemove', function () {
        if (!result) {
            alert('cancelled');
        }
    });
}, 1000);

यह कैसे काम करता है: फ़ाइल चयन संवाद खुला है, दस्तावेज़ माउस सूचक घटनाओं को प्राप्त नहीं करता है। डायलॉग को वास्तव में प्रकट करने और ब्राउज़र विंडो को ब्लॉक करने की अनुमति देने के लिए 1000ms देरी है। क्रोम और फ़ायरफ़ॉक्स (केवल विंडोज) में चेक किया गया।

लेकिन यह निश्चित रूप से रद्द किए गए संवाद का पता लगाने का एक विश्वसनीय तरीका नहीं है। हालाँकि, आपके लिए कुछ UI व्यवहार में सुधार हो सकता है।


एक बड़ी कमी फोन और टैबलेट पर है, वे सामान्य रूप से चूहों का उपयोग नहीं करते हैं!
पीटर

0

यहाँ मेरा समाधान है, फ़ाइल इनपुट फ़ोकस का उपयोग करके (किसी टाइमर का उपयोग नहीं)

var fileInputSelectionInitiated = false;

function fileInputAnimationStart() {
    fileInputSelectionInitiated = true;
    if (!$("#image-selector-area-icon").hasClass("fa-spin"))
        $("#image-selector-area-icon").addClass("fa-spin");
    if (!$("#image-selector-button-icon").hasClass("fa-spin"))
        $("#image-selector-button-icon").addClass("fa-spin");
}

function fileInputAnimationStop() {
    fileInputSelectionInitiated = false;
    if ($("#image-selector-area-icon").hasClass("fa-spin"))
        $("#image-selector-area-icon").removeClass("fa-spin");
    if ($("#image-selector-button-icon").hasClass("fa-spin"))
        $("#image-selector-button-icon").removeClass("fa-spin");
}

$("#image-selector-area-wrapper").click(function (e) {
    $("#fileinput").focus();
    $("#fileinput").click();
});

$("#preview-image-wrapper").click(function (e) {
    $("#fileinput").focus();
    $("#fileinput").click();
});

$("#fileinput").click(function (e) {
    fileInputAnimationStart();
});

$("#fileinput").focus(function (e) {
    fileInputAnimationStop();
});

$("#fileinput").change(function(e) {
    // ...
}


अपने स्निपेट को चलाने से मुझेError: { "message": "Uncaught SyntaxError: missing ) after argument list", "filename": "https://stacksnippets.net/js", "lineno": 51, "colno": 1 }
कॉनक्सो

0

यह सबसे अच्छी तरह से हैक किया गया है, लेकिन यहां एक उपयोगकर्ता ने किसी फ़ाइल को अपलोड किया है या नहीं, यह पता लगाने के लिए मेरे समाधान का एक कार्यशील उदाहरण है, और केवल यह सुनिश्चित करने की अनुमति देता है कि क्या उन्होंने कोई फ़ाइल अपलोड की है।

मूल रूप से छिपाने Continue, Save, Proceedया जो कुछ भी अपने बटन है। फिर जावास्क्रिप्ट में आप फ़ाइल का नाम लेते हैं। यदि फ़ाइल नाम का कोई मान नहीं है, तो Continueबटन न दिखाएं । यदि इसका कोई मान है, तो बटन दिखाएं। यह तब भी काम करता है जब वे पहले एक फ़ाइल अपलोड करते हैं और फिर वे एक अलग फ़ाइल अपलोड करने का प्रयास करते हैं और रद्द करते हैं।

यहाँ कोड है।

HTML:

<div class="container">
<div class="row">
    <input class="file-input" type="file" accept="image/*" name="fileUpload" id="fileUpload" capture="camera">
    <label for="fileUpload" id="file-upload-btn">Capture or Upload Photo</label>
</div>
<div class="row padding-top-two-em">
    <input class="btn btn-success hidden" id="accept-btn" type="submit" value="Accept & Continue"/>
    <button class="btn btn-danger">Back</button>
</div></div>

जावास्क्रिप्ट:

$('#fileUpload').change(function () {
    var fileName = $('#fileUpload').val();
    if (fileName != "") {
        $('#file-upload-btn').html(fileName);
        $('#accept-btn').removeClass('hidden').addClass('show');
    } else {
        $('#file-upload-btn').html("Upload File");
        $('#accept-btn').addClass('hidden');
    }
});

सीएसएस:

.file-input {
    width: 0.1px;
    height: 0.1px;
    opacity: 0;
    overflow: hidden;
    position: absolute;
    z-index: -1; 
}

.file-input + label {
    font-size: 1.25em;
    font-weight: normal;
    color: white;
    background-color: blue;
    display: inline-block;
    padding: 5px;
}

.file-input:focus + label,
.file-input + label:hover {
    background-color: red;
}

.file-input + label {
    cursor: pointer;
}

.file-input + label * {
    pointer-events: none;
}

CSS के लिए इसमें से बहुत कुछ वेबसाइट और बटन को सभी के लिए सुलभ बनाना है। अपने बटन को स्टाइल करें जो भी आपको पसंद है।


0

खैर, यह आपके सवाल का सही जवाब नहीं देता है। मेरी धारणा यह है कि, आपके पास एक परिदृश्य है, जब आप एक फ़ाइल इनपुट जोड़ते हैं, और फ़ाइल चयन को लागू करते हैं, और यदि उपयोगकर्ता हिट रद्द करता है, तो आप बस इनपुट हटा देते हैं।

यदि यह मामला है, तो: खाली फ़ाइल इनपुट क्यों जोड़ा जा रहा है?

मक्खी पर एक बनाएँ, लेकिन इसे डोम में तभी भरें जब वह अंदर भर जाए।

    var fileInput = $("<input type='file' name='files' style='display: none' />");
    fileInput.bind("change", function() {
        if (fileInput.val() !== null) {
            // if has value add it to DOM
            $("#files").append(fileInput);
        }
    }).click();

इसलिए यहाँ मैं मक्खी पर <input type = "file" /> बनाता हूँ, इसे बदलने की घटना से बाँधता हूँ और फिर तुरंत क्लिक पर आह्वान करता हूँ। परिवर्तन पर केवल तभी फायर होगा जब उपयोगकर्ता किसी फ़ाइल का चयन करता है और ओके को हिट करता है, अन्यथा DOM में इनपुट नहीं जोड़ा जाएगा, इसलिए सबमिट नहीं किया जाएगा।

यहाँ काम करने का उदाहरण: https://jsfiddle.net/69g0Lxno/3/


0

// ब्लर के बजाय होवर का उपयोग करें

var fileInput = $("#fileInput");

if (fileInput.is(":hover") { 

    //open
} else {

}

0

यदि आपको पहले से ही JQuery की आवश्यकता है, तो यह समाधान काम कर सकता है (यह वास्तव में मेरे मामले में आवश्यक वही कोड है, हालांकि एक वादा का उपयोग करना कोड को केवल तब तक इंतजार करने के लिए मजबूर करना है जब तक फ़ाइल चयन हल नहीं हो जाता है):

await new Promise(resolve => {
    const input = $("<input type='file'/>");
    input.on('change', function() {
        resolve($(this).val());
    });
    $('body').one('focus', '*', e => {
        resolve(null);
        e.stopPropagation();
    });
    input.click();

});


0

इस थ्रेड में कई प्रस्तावित समाधान हैं और जब उपयोगकर्ता चयन फ़ाइल पर "रद्द करें" बटन पर क्लिक करता है, तो यह पता लगाने में कठिनाई होती है कि कई लोगों को प्रभावित करता है।

तथ्य यह है कि उपयोगकर्ता ने फ़ाइल चयन बॉक्स पर "रद्द करें" बटन पर क्लिक किया है या नहीं, इसका पता लगाने का कोई 100% विश्वसनीय तरीका नहीं है । लेकिन मज़बूती से यह पता लगाने के तरीके हैं कि क्या उपयोगकर्ता ने फ़ाइल को इनपुट फ़ाइल में जोड़ा है । तो यह इस उत्तर की मूल रणनीति है!

मैंने इस उत्तर को जोड़ने का फैसला किया क्योंकि स्पष्ट रूप से अन्य उत्तर अधिकांश ब्राउज़रों पर काम नहीं करते हैं या मोबाइल उपकरणों पर गारंटी नहीं देते हैं।

संक्षेप में कोड 3 बिंदुओं पर आधारित है:

  1. इनपुट फ़ाइल शुरू में js में "मेमोरी" में गतिशील रूप से बनाई गई है (हम इसे इस समय "HTML" में नहीं जोड़ते हैं);
  2. फ़ाइल जोड़ने के बाद फिर HTML में इनपुट फ़ाइल जोड़ी जाती है, अन्यथा कुछ भी नहीं होता है;
  3. फ़ाइल का निष्कासन HTML से इनपुट फ़ाइल को एक विशिष्ट घटना द्वारा हटाकर किया जाता है, जिसका अर्थ है कि फ़ाइल का "संपादन" / "संशोधन" पुरानी इनपुट फ़ाइल को हटाकर एक नया बनाने के द्वारा किया जाता है।

बेहतर समझ के लिए नीचे दिए गए कोड और नोट्स को भी देखें।

[...]
<button type="button" onclick="addIptFl();">ADD INPUT FILE!</button>
<span id="ipt_fl_parent"></span>
[...]
function dynIptFl(jqElInst, funcsObj) {
    if (typeof funcsObj === "undefined" || funcsObj === "") {
        funcsObj = {};
    }
    if (funcsObj.hasOwnProperty("before")) {
        if (!funcsObj["before"].hasOwnProperty("args")) {
            funcsObj["before"]["args"] = [];
        }
        funcsObj["before"]["func"].apply(this, funcsObj["before"]["args"]);
    }
    var jqElInstFl = jqElInst.find("input[type=file]");

    // NOTE: Open the file selection box via js. By Questor
    jqElInstFl.trigger("click");

    // NOTE: This event is triggered if the user selects a file. By Questor
    jqElInstFl.on("change", {funcsObj: funcsObj}, function(e) {

        // NOTE: With the strategy below we avoid problems with other unwanted events
        // that may be associated with the DOM element. By Questor
        e.preventDefault();

        var funcsObj = e.data.funcsObj;
        if (funcsObj.hasOwnProperty("after")) {
            if (!funcsObj["after"].hasOwnProperty("args")) {
                funcsObj["after"]["args"] = [];
            }
            funcsObj["after"]["func"].apply(this, funcsObj["after"]["args"]);
        }
    });

}

function remIptFl() {

    // NOTE: Remove the input file. By Questor
    $("#ipt_fl_parent").empty();

}

function addIptFl() {

    function addBefore(someArgs0, someArgs1) {
    // NOTE: All the logic here happens just before the file selection box opens.
    // By Questor

        // SOME CODE HERE!

    }

    function addAfter(someArgs0, someArgs1) {
    // NOTE: All the logic here happens only if the user adds a file. By Questor

        // SOME CODE HERE!

        $("#ipt_fl_parent").prepend(jqElInst);

    }

    // NOTE: The input file is hidden as all manipulation must be done via js.
    // By Questor
    var jqElInst = $('\
<span>\
    <button type="button" onclick="remIptFl();">REMOVE INPUT FILE!</button>\
    <input type="file" name="input_fl_nm" style="display: block;">\
</span>\
');

    var funcsObj = {
        before: {
            func: addBefore,
            args: [someArgs0, someArgs1]
        },
        after: {
            func: addAfter,

            // NOTE: The instance with the input file ("jqElInst") could be passed
            // here instead of using the context of the "addIptFl()" function. That
            // way "addBefore()" and "addAfter()" will not need to be inside "addIptFl()",
            // for example. By Questor
            args: [someArgs0, someArgs1]

        }
    };
    dynIptFl(jqElInst, funcsObj);

}

धन्यवाद! = D


0

हमने नीचे की तरह कोणीय में हासिल किया।

    1. इनपुट प्रकार फ़ाइल पर क्लिक इवेंट बांधें।
      1. विंडो के साथ फोकस ईवेंट अटैच करें और कंडीशन जोड़ें अगर अपलोडपैन सच है तो कंसोल दिखाएं।
      2. जब इनपुट प्रकार फ़ाइल पर क्लिक करें बूलियन अपलोडपैनल मूल्य सच है। और संवाद बॉक्स दिखाई देता है।
      3. जब रद्द करें या Esc बटन क्लिक करें तो संवाद बॉक्स डिस्पेंसरी और कंसोल दिखाई देते हैं।

एचटीएमएल

 <input type="file" formControlName="FileUpload" click)="handleFileInput($event.target.files)" />
          />

टीएस

this.uploadPanel = false;
handleFileInput(files: FileList) {
    this.fileToUpload = files.item(0);
    console.log("ggg" + files);
    this.uploadPanel = true;
  }



@HostListener("window:focus", ["$event"])
  onFocus(event: FocusEvent): void {
    if (this.uploadPanel == true) {
        console.log("cancel clicked")
        this.addSlot
        .get("FileUpload")
        .setValidators([
          Validators.required,
          FileValidator.validate,
          requiredFileType("png")
        ]);
      this.addSlot.get("FileUpload").updateValueAndValidity();
    }
  }

0

बस अपने इनपुट पर 'परिवर्तन' श्रोता जोड़ें जिसका प्रकार फ़ाइल है। अर्थात

<input type="file" id="file_to_upload" name="file_to_upload" />

मैंने jQuery का उपयोग किया है और जाहिर है कि कोई भी वैलीना जेएस (आवश्यकता के अनुसार) का उपयोग कर सकता है।

$("#file_to_upload").change(function() {

            if (this.files.length) {

            alert('file choosen');

            } else {

            alert('file NOT choosen');

            }

    });

.change()अगर उपयोगकर्ता फाइल पिकर पर "रद्द" पर क्लिक करता है तो मज़बूती से नहीं कहा जाता है।
बेन व्हीलर

@benWheeler, मैंने इसे क्रोम और फ़ायरफ़ॉक्स दोनों पर चेक किया है और इसने मेरे काम किया लेकिन अन्य ब्राउज़रों पर परीक्षण नहीं किया गया।
नावेद अली

0
    enter code here
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <h1>Hello</h1>
    <div id="cancel01">
      <button>Cancel</button>
    </div>

    <div id="cancel02">
      <button>Cancel</button>
    </div>

    <div id="cancel03">
      <button>Cancel</button>
    </div>

    <form>
      <input type="file" name="name" placeholder="Name" />
    </form>

    <script>
      const nameInput = document.querySelector('input[type="file"]');

      /******
       *The below code if for How to detect when cancel is clicked on file input
       ******/
      nameInput.addEventListener('keydown', e => {
        /******
         *If the cancel button is clicked,then you should change the input file value to empty
         ******/

        if (e.key == 'Backspace' || e.code == 'Backspace' || e.keyCode == 8) {
          console.log(e);

          /******
           *The below code will delete the file path
           ******/
          nameInput.value = '';
        }
      });
    </script>
  </body>
</html>

कोड-केवल उत्तरों को निम्न गुणवत्ता माना जाता है: यह सुनिश्चित करना सुनिश्चित करें कि आपका कोड क्या करता है और यह समस्या को कैसे हल करता है। यह पूछने वाले और भविष्य के पाठकों दोनों की मदद करेगा यदि आप अपनी पोस्ट में अधिक जानकारी जोड़ सकते हैं। पूरी तरह से कोड-आधारित उत्तर की व्याख्या
कैलोस

0

छिपे हुए इनपुट के साथ फ़ाइल चयन के लिए समाधान

नोट: यह कोड रद्दीकरण का पता नहीं लगाता है, यह एक सामान्य मामले में इसका पता लगाने की आवश्यकता को दरकिनार करने का एक तरीका प्रदान करता है जिसमें लोग इसका पता लगाने की कोशिश करते हैं।

मैं एक छिपे हुए इनपुट का उपयोग करके फ़ाइल अपलोड के लिए एक समाधान की तलाश में यहां आया था, मेरा मानना ​​है कि फ़ाइल इनपुट रद्द करने का पता लगाने का एक सबसे आम कारण है (खुले फ़ाइल संवाद -> यदि कोई फ़ाइल चयनित थी, तो कुछ चलाएं कोड, नहीं तो कुछ नहीं), यहाँ मेरा समाधान है:

var fileSelectorResolve;
var fileSelector = document.createElement('input');
fileSelector.setAttribute('type', 'file');

fileSelector.addEventListener('input', function(){
   fileSelectorResolve(this.files[0]);
   fileSelectorResolve = null;
   fileSelector.value = '';
});

function selectFile(){
   if(fileSelectorResolve){
      fileSelectorResolve();
      fileSelectorResolve = null;
   }
   return new Promise(function(resolve){
      fileSelectorResolve = resolve;
      fileSelector.dispatchEvent(new MouseEvent('click'));
   });
}

उपयोग उदाहरण:

ध्यान दें कि यदि कोई फ़ाइल नहीं चुनी गई थी, तो पहली पंक्ति केवल एक बार वापस आ जाएगी selectFile()(या यदि आप fileSelectorResolve()कहीं और से कॉल की जाती हैं)।

async function logFileName(){
   const file = await selectFile();
   if(!file) return;
   console.log(file.name);
}

एक और उदाहरण:

async function uploadFile(){
   const file = await selectFile();
   if(!file) return;

   // ... make an ajax call here to upload the file ...
}

83.0 क्रोम में, मुझे उपयोगकर्ता को रद्द करने पर इनपुट इवेंट के लिए कोई कॉलबैक नहीं मिलता है, और न ही 2 पर प्रयास करें
सोयालेन ग्राहम

1
@SoylentGraham हां, क्योंकि यह कोड रद्द करने का पता नहीं लगाता है, यह एक सामान्य मामले में इसे पता लगाने की आवश्यकता को दरकिनार करने का एक तरीका प्रदान करता है जिसमें लोग इसका पता लगाने की कोशिश करते हैं। चूंकि मैं इसके बारे में स्पष्ट नहीं था, इसलिए मैं इस टिप्पणी को अपने उत्तर में जोड़ रहा हूं।
आलू

मेरा बुरा मुझे लगता है, मैं आपके जवाब को गलत मानता हूं क्योंकि "यह आपको बताता है कि उपयोगकर्ता 2 वें प्रयास पर रद्द कर दिया गया है"
सोयेलेंट ग्राहम 6

-1

आप इनपुट फ़ील्ड पर एक jquery परिवर्तन श्रोता बना सकते हैं और पता लगा सकते हैं कि उपयोगकर्ता फ़ील्ड के मान से रद्द या बंद अपलोड विंडो है।

यहाँ एक उदाहरण है:

//when upload button change
$('#upload_btn').change(function(){
    //get uploaded file
    var file = this.files[0];

    //if user choosed a file
    if(file){
        //upload file or perform your desired functiuonality
    }else{
        //user click cancel or close the upload window
    }
});

कोई विचार नहीं है कि यह नीचा क्यों है - यह वही है जिसकी मुझे तलाश थी। धन्यवाद! 🙂
user1274820
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.