I need to get a file on load to input.
This code works in chrome, opera and firefox but not with IE:
$("input:file").change(function ()
{
// Get a reference to the fileList
var files = !!this.files ? this.files : [];
// If no files were selected, or no FileReader support, return
if ( !files.length || !window.FileReader ) return;
// Only proceed if the selected file is an text
if ( /^text/.test( files[0].type ) )
{
var reader = new FileReader();
reader.readAsText( files[0] );
reader.onloadend = function()
{
restoreCSS(this.result);
}
}
}
In IE !!this.files return false. Thank's for advance.
Which version of IE are you using? FileReader isn't supported in IE until version 10.
As #apsillers commented, there's another question asking about how to imitate FileReader support in browsers that don't support it. I believe they all require some sort of plugin (Flash/Silverlight), as before the FileReader API, JavaScript did not have any access to the file system.
Related
I have the following javascript which provides an image upload button and displays the image:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#target').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#imgInp").change(function(){
readURL(this);
});
The full jsfiddle is here:
http://jsfiddle.net/6NXwv/
This code works on every mobile browser I've tried except for the stock Android browser. Specifically images only fail to load if they are stored remotely but appear in the gallery (for example synced facebook or picasa images). Now I know FileReader is only for LOCAL files however chrome browser, opera, and firefox mobile have no issues.
I checked the FileReader error code, it appears that gallery images from facebook/picasa return NOT_FOUND_ERR:
https://developer.mozilla.org/en-US/docs/Web/API/FileError
If this is a case of FileReader not able to read remote files why does it work in all other mobile browsers?
I can't find anyone else having this exact issue, everything I google keeps returning this result:
Issue with stock Browser picking photos from Gallery
However the mime-type appears to be detected correctly. The mime-type shows up and the filename shows the correct name but the actual data isn't there (also File.size reports '0'). I've been able to recreate this on the stock android browser on 4.4 and 4.3. Haven't tested older versions.
In short when selecting photos via the gallery, local files and new images taken with the camera load correctly but remote facebook/picasa files (on 4.4 at least they have little fb/picasa icons on their thumbnails in the gallery) do not load. Only occurs in stock browser.
The error you face have 2 explanation.
First explanation is that the files "Images" that you tried to read with HTML5 API FileReader are looked or on use by other applications "like Facebook or Picasa" and in this case you can do nothing about it from js unless you have physical access to the hardware "Phone".
second explanation which is more likely is some browsers can't fire the event onload of FileReader because they are not fully supporting this HTML5 API. you can read more about this in caniuse website. And that can be solve by changing the event onload to onloadend.
here is how your code should be :
var reader = new FileReader();
reader.onloadend = function () {
console.log(reader.result);
};
reader.readAsDataURL(file);
here is example: jsfiddle
here is Demo: Demo FileReader Html5
<input id="fileinput" name="arquivo[]" type="file" multiple="multiple" onchange="FileDetails()"/>
<var id="file_List"></var>
<button type="button" onclick="Click()">Click Me!</button>
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"></script>
<script>
// simple routine to put content of file input files into memory
G_Array = [];
G_Cont_Upload = 0;
function Click()
{
var a = 1; // this is only to check the content of global variable as google chrome does not stop inside f_ReadFile
}
function FileDetails()
{
var file_arr = [];
if (typeof (FileReader) != "undefined")
{
var files = $('#fileinput')[0].files;
var reader = [];
for (var i = 0; i < files.length; i++)
{
var FileDet = files[i];
var name = FileDet.name;
var Size = FileDet.size;
var Obj = {Name: FileDet.name, SizeInicial : FileDet.size};
G_Array.push(Obj);
reader[i] = new FileReader();
function f_ReadFile(e)
{
var content = e.target.result;
G_Array[G_Cont_Upload].SizeAtual = content.length;
G_Array[G_Cont_Upload].Content = content; // content base 64
G_Cont_Upload++;
}
reader[i].onload = f_ReadFile;
reader[i].readAsDataURL(FileDet);
}
}
else
{
alert("This browser does not support HTML5 FileReader.");
}
}
</script>
</body>
I have a application similar to the example http://jsfiddle.net/jonathansampson/K3A9r/
But if I use this concept for file upload on a iPad/android it does not work. The image is not loaded into the browser wether with onload() nor with onloadend()
html:
<input type="file" name="myFileSelect" />
js:
// Bind to the change event of our file input
$("input[name='myFileSelect']").on("change", function(){
// Get a reference to the fileList
var files = !!this.files ? this.files : [];
// If no files were selected, or no FileReader support, return
if ( !files.length || !window.FileReader ) return;
// Only proceed if the selected file is an image
if ( /^image/.test( files[0].type ) ) {
// Create a new instance of the FileReader
var reader = new FileReader();
// Read the local file as a DataURL
reader.readAsDataURL( files[0] );
// When loaded, set image data as background of page
reader.onloadend = function(){
$("html").css("background-image", "url(" + this.result + ")");
}
}
});
I don't believe the onloadend event is well supported in android or ios. IE 10 does not support this event on FileReader as well, I think. Perhaps you should rely on the onload event instead.
File.API works from android browser 3.0+
or user firefox on the android device
http://mobilehtml5.org/
I upload an image file from my PC and then read it as dataurl. Then pass it to img element to preview it. It is working fine in firefox. But in chrome and IE, it doesn't get the src from the file reader.
Here is what i'm doing,
var image = document.createElement("img");
var thumbnail = document.getElementById("thumbnail");
image.file = file;
thumbnail.appendChild(image);
function handlefilereader(evt){
image.src = evt.target.result;
}
var reader = new FileReader()
reader.onload = handlefilereader;
reader.readAsDataURL(file);
image.id = count;
count++;
image.draggable = true;
image.ondragstart = dragIt;
alert(image.src);
Filereader may not be supported in your browser versions. See this compatibility chart.
http://caniuse.com/filereader
Also, event.target is not fully browser compatible. Consider
var target = evt.target || evt.srcElement;
image.src = target.result;
Like people here mentioned, File API is not supported in IE. But no one mentioned a possible solution. Here is one --> FileReader + flash
So you can still use FileAPI in IE.
My Code:
var data = $(input)[0];
var file = data.files[0];
var reader = new FileReader();
reader.onload = function (e) {
value = e.target.result;
try {
top.document.getElementById('formDesignContents').contentWindow.updateFormFromToolbar(CURRENT_ATTRIBUTE, value, opts);
} catch (err) {
alert("error connecting to formDesignContents iframe from the toolbar");
}
}
reader.readAsDataURL(file);
It works in GoogleChrome but not IE. For IE, it does not recognize the attribute files under the input element. The jquery is to dereference a jquery object back into standard html element.
Is there another way to accomplish for IE to work? I can easily do one of those
if(IE){...}else{...}
blocks of code. I just dont see why it doesnt recognize those items.
Has anyone else encountered this?
IE doesn't support FileReader, so I'd expect your script to crash on this line:
var reader = new FileReader();
Unless you are using IE10?
https://developer.mozilla.org/en/DOM/FileReader#Browser_compatibility
I noticed a blog post from Google that mentions the ability to paste images directly from the clipboard into a Gmail message if you're using the latest version of Chrome. I tried this with my version of Chrome (12.0.742.91 beta-m) and it works great using control keys or the context menu.
From that behavior I need to assume that the latest version of webkit used in Chrome is able to deal with images in the Javascript paste event, but I have been unable to locate any references to such an enhancement. I believe ZeroClipboard binds to keypress events to trigger its flash functionality and as such wouldn't work through the context menu (also, ZeroClipboard is cross-browser and the post says this works only with Chrome).
So, how does this work and where the enhancement was made to Webkit (or Chrome) that enables the functionality?
I spent some time experimenting with this. It seems to sort of follow the new Clipboard API spec. You can define a "paste" event handler and look at event.clipboardData.items, and call getAsFile() on them to get a Blob. Once you have a Blob, you can use FileReader on it to see what's in it. This is how you can get a data url for the stuff you just pasted in Chrome:
document.onpaste = function (event) {
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
console.log(JSON.stringify(items)); // might give you mime types
for (var index in items) {
var item = items[index];
if (item.kind === 'file') {
var blob = item.getAsFile();
var reader = new FileReader();
reader.onload = function (event) {
console.log(event.target.result); // data url!
};
reader.readAsDataURL(blob);
}
}
};
Once you have a data url you can display the image on the page. If you want to upload it instead, you could use readAsBinaryString, or you could put it into an XHR using FormData.
Edit: Note that the item is of type DataTransferItem. JSON.stringify might not work on the items list, but you should be able to get mime type when you loop over items.
The answer by Nick seems to need small changes to still work :)
// window.addEventListener('paste', ... or
document.onpaste = function (event) {
// use event.originalEvent.clipboard for newer chrome versions
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
console.log(JSON.stringify(items)); // will give you the mime types
// find pasted image among pasted items
var blob = null;
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") === 0) {
blob = items[i].getAsFile();
}
}
// load image if there is a pasted image
if (blob !== null) {
var reader = new FileReader();
reader.onload = function(event) {
console.log(event.target.result); // data url!
};
reader.readAsDataURL(blob);
}
}
Example running code: http://jsfiddle.net/bt7BU/225/
So the changes to nicks answer were:
var items = event.clipboardData.items;
to
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
Also I had to take the second element from the pasted items (first one seems to be text/html if you copy an image from another web page into the buffer). So I changed
var blob = items[0].getAsFile();
to a loop finding the item containing the image (see above)
I didn't know how to answer directly to Nick's answer, hope it is fine here :$ :)
As far as I know -
With HTML 5 features(File Api and the related) - accessing clipboard image data is now possible with plain javascript.
This however fails to work on IE (anything less than IE 10). Don't know much about IE10 support also.
For IE the optiens that I believe are the 'fallback' options are
either using Adobe's AIR api
or
using a signed applet