2015-06-24 7 views
7

Mam plik wejściowy przeglądarki plików <input type="file" id="browse-button"/> w moim kodzie HTML.JavaScript przechwycony "Ctrl + O" nie otwiera mojego okna dialogowego pliku

Mam inny przycisk z identyfikatorem choose-file-button, który po kliknięciu wywołuje document.getElementById("browse-button").click();. Po kliknięciu tego przycisku kliknie on odpowiednio #browse-button i otworzy się okno dialogowe pliku.

Teraz wziąłem kod this answer przechwycić Ctrl+O przyciśnięcie i otworzyć okno dialogowe pliku, więc mam to:

$(window).bind('keydown', function(e) 
{ 
    if (e.ctrlKey || e.metaKey) 
    { 
     switch (String.fromCharCode(e.which).toLowerCase()) 
     { 
      case 's': 
       e.preventDefault(); 
       // doesn't matter for this question 
       return false; 
      case 'o': 
       e.preventDefault(); 
       document.getElementById("choose-file-button").click(); 
       return false; 
     } 
    } 
    return true; 
}); 

Jak widać, kiedy przechwycić Ctrl+O klikam na mój przycisk #choose-file-button, który wywołuje document.getElementById("browse-button"); w swojej obsadzie onclick. W tym module obsługi kliknięć wstawiłem punkt przerwania, a po naciśnięciu klawisza Ctrl+O osiągnięto ten punkt przerwania. Jednak okno dialogowe pliku nigdy się nie wyświetla.

Poprzez debugowanie, I okazało się, że jeśli umieścić alert(...); po linii #choose-file-button click(), wówczas pojawia się alert i normalną stronę dialogowe „Otwórz plik” pojawia się (nie mój dialogowe pliku). Jeśli jednak nie mam tego alertu, nic się nie pokazuje.

Czy to błąd? Jak mogę to naprawić i wyświetlić okno dialogowe pliku przechwycone Ctrl+O?

Edytuj: Właśnie testowałem w przeglądarce Chrome i działa idealnie. Jednak nadal nie działa w Firefoksie.

+0

próbowałeś użyciu JQuery do uruchomienia kliknięcie '$ ("# wybierać-file-przycisk"). kliknij() zamiast używać getElementById? – Osuwariboy

+0

@Osuwariboy mam teraz, ale to niczego nie zmienia. – Jashaszun

+0

Twój problem wydaje się podobny do tego: [przesuń ctrl + s] (http://stackoverflow.com/questions/14860759/cant-override-ctrls-in-firefox-using-jquery-hotkeys). Może mógłbyś spróbować swoich sugestii? – Osuwariboy

Odpowiedz

9

Trochę magii bezpieczeństwa przeglądarki dzieje się tutaj. Podczas korzystania z limitów czasu lub interwałów lub innych metod, które próbuję, kod działa normalnie, ale przeglądarka po prostu odmawia otwarcia okna dialogowego przesyłania plików. Jest to prawdopodobnie celowe, aby powstrzymać złośliwe JS przed próbami pobrania plików użytkowników bez zgody. Jeśli jednak zostanie wywołane zdarzenie kliknięcia łącza, działa ono doskonale przy użyciu jQuery lub zwykłego JS.

Edytuj: Zgodnie z podejrzeniami większość przeglądarek śledzi, czy zdarzenie jest zaufane, czy nie, w zależności od typu zdarzenia oraz od tego, czy zostało ono utworzone przez użytkownika, czy wygenerowane programowo. Se this answer, aby uzyskać szczegółowe informacje. Jak widać, ponieważ zdarzeń na klawiaturze nie ma na liście, nigdy nie można im ufać.

Test JSFiddle

<form action="#" method="post"> 
    <div> 
     <input type="file" id="myfile" name="myfile" /> <a href="#" id="mylink" accesskey="o">Click me</a> 
    </div> 
</form> 

$("#mylink").click(function() { 
    $("#myfile").click(); 
}); 

$(window).bind('keydown', function (e) { 
    if (e.ctrlKey || e.metaKey) { 
     switch (String.fromCharCode(e.which).toLowerCase()) { 
      case 'o': 
       e.preventDefault(); 
       console.log("1a"); 

       $("#myfile").click(); 
       //alert("hello"); 

       console.log("1b"); 
       return false; 
     } 
    } 
    return true; 
}); 

Myślę, że są tylko dwie opcje tutaj, a oni zarówno obejścia, a nie rozwiązują.

  • Jednym z nich jest użycie łącza, aby wywołać okno dialogowe wysyłania plików, i prosić ludzi, aby użyć Alt + Shift + O zamiast Ctrl + O (bo dodał accesskey attribute do łącza w przykładzie).
  • Inną alternatywą jest użycie jednego z nowych API JavaScript HTML5 dla drag-drop file uploading.

Dodatek: Próbowałem również używać czystego JavaScript w przeglądarce Firefox, aby pobrać zdarzenie click i sprawdzić, czy jest zaufany za pomocą właściwości isTrusted. Za kliknięcia linku zwrócono true. Jednak próba przechowania i ponownego użycia zdarzenia w innym miejscu nie działa, ponieważ została już wysłana do czasu uzyskania odnośnika. Ponadto, nieoczekiwanie, utworzenie nowego zdarzenia i próba ustawienia isTrusted = true nie działa, ponieważ jest to tylko do odczytu.

+0

Zobacz także http://stackoverflow.com/a/29873845/ – guest271314

+0

@ guest271314 Nice link! Miałem silne podejrzenie, że przeglądarka może odróżnić kliknięcia rzeczywiste od programowych. – BoffinbraiN

+0

@BoffinbraiN Dziękuję za szczegółową odpowiedź i przykro mi, że nie byłem tutaj, aby zadawać pytania/udzielać odpowiedzi/głosować wcześniej ... Byłem poza miastem. W każdym razie mogę sprawdzić, że HTML5 API, ale jeśli wygląda na zbyt trudny w użyciu, po prostu pozostanę bez skrótów klawiaturowych dla pliku IO (ponieważ są jeszcze przyciski na stronie, które działają idealnie dobrze). – Jashaszun

4

Przeglądarka wiele skrótów Ctrl + do własnych poleceń, na przykład CTRL + O, aby otworzyć plik (w firefox).

W tym samym czasie przeglądarka zachowuje się inaczej, gdy próbujesz zastąpić takie skróty w javascript. Niektóre przeglądarki umożliwiają to, niektóre nie, a czasami domyślna akcja przeglądarki może pojawić się wraz z działaniem skryptu javascript.

Oto kolejny wątek omawiający tę topic.

Prawdopodobnie najlepsze, co możesz zrobić, to wybrać inny skrót.

4

Możesz wypróbować bibliotekę Mousetrap. Zastępuje większość problemów związanych z przechwytywaniem klawiszy. Oficjalna strona i kompletne refference:

https://craig.is/killing/mice

Powodzenia

+0

Aby to wyjaśnić, OP chciał przesłonić kombinację klawiszy Ctrl + O, a nie skonfigurować zdarzenia kliknięcia, co nie jest łatwe do wdrożenia. – BoffinbraiN

+0

Biblioteka Mousetrap nie polega na ustawianiu zdarzenia click, jest dla oppositte, jest unikaniem użycia myszy, wszystko za pomocą klawiatury. –

+0

Aha ... Rozumiem. Ładne narzędzie, ale z powodu problemów wymienionych w mojej odpowiedzi, żadna biblioteka JS nie może obejść zabezpieczeń przeglądarki. Próbowałem go z Fiddle [tutaj] (http://jsfiddle.net/w26jo08u/). – BoffinbraiN