I Can't get div background image to change with onchange in a input type file - by Javascript for IE and Safari - works in FF and Chrome

StackOverflow https://stackoverflow.com/questions/19648293

سؤال

if you open the fiddle http://jsfiddle.net/FyJR3/3 in both Firefox and IE and when you select a local image - The Div background image does not disply in ie - but it does display in firefox - so i am looking to find a solution to this cross browser incompatability :) - also note it does NOT use jQuery - it uses prototype.js and scriptaculous.js

I am a novice at Javascript and have modified and used others code from stackoverflow.com, to make a Visual Cropper for my site - I use the Input type=File

<input id="attach1" name="attach1" type="file" size=60 style="width:390px;">

This is the divs i am trying to change (that wont work in IE and Safari) Is working in firefox and Chrome - the extra <div></div> were a suggestion from another persons answers on this board to a similar (not the same problem) - they made no difference and can be removed. clear512px.png is just a clear 512px square overlay to hold the div open and at size for the cropping. (Code wont work without it - so far in firefox and chrome)

<div style="width:512px; height:512px;">
    <div></div>
    <div id="theImageToCrop" align="center" style="background-image: url(../pics/No-Image.jpg); background-position:center; background-repeat:no-repeat; background-size:contain; max-height:512px; max-width:512px; width:100%; border: 1px solid #808080; position: relative;">
        <div></div>
        <div id="testWrap" style="height:512px; width:512px; text-align:center; vertical-align:middle;">
        <div></div>
            <img src="../cropper/tests/clear512px.png" src= alt="test image" id="testImage" style="width:100%;" />
        </div>
    </div>
</div>

I have the below two scripts at the bottom of the page just before the </body> tag - This works in chrome and Firefox - but not in IE and Safari

<script type="text/javascript">
  function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object

    // Loop through the FileList and render image files as thumbnails.
    for (var i = 0, f; f = files[i]; i++) {
alert(i + " " + files[i]);
      // Only process image files.
      if (!f.type.match('image.*')) {
        continue;
      }

      var reader = new FileReader();

      // Closure to capture the file information.
          reader.onload = (function(theFile) {
        return function(e) {
          // Render thumbnail.
         var div0 = document.getElementById('theImageToCrop');
            div0.style.backgroundImage = "url(" + e.target.result + ")";
       };
      })(f);

      // Read in the image file as a data URL.
      reader.readAsDataURL(f);
    }
  }  

  document.getElementById('attach1').addEventListener('change', handleFileSelect, false);
</script>

<script type="text/javascript">
(window.onload = function(){

var img = document.getElementById('theImageToCrop').style.backgroundImage;
img.onload = function() {
    if(img.height > img.width) {
        img.height = '100%';
        img.width = 'auto';
    }
};

}());
</script>

What I need to do is to display the file(image) from the the input and display it in the ID="theImageToCrop" Div - so as the user can see it - and the rest of the code to zoom and crop is functional - its hosted on a windows server 2008 - My primary server code is ASP classic - with smatterings of ASP.net, obviously Javascript (My weak point) and also loaded and using "prototype.js" and "scriptaculous.js" and "cropper.js" script sources - NO jQuery use.

I am still a novice at JS so please can you make the answer/reasoning as simple as possible

Your help on this is very appreciated -Thanks in Advance

          • Addded Full code below below * * * * * *

Below is full code of a lighter page with which I am needing to get the results - this is live at http://www.VintageAntiqueRetro.com/testcropping.asp - but page is stripped of the upload function (that upload section works a treat) - I just need to be able to select 1 (one) file and have the div change in all browsers. Thanks Guys :)

<%@ Language=VBScript %> 
<% option explicit 
Response.Expires = -1
Server.ScriptTimeout = 600
Session.CodePage  = 65001
Dim thispageaddress, adStateOpen, sPicNum, oldfile, fm, itisdone, jpeg
Dim errMsgs, verified, ulog, thelistingnum, origdir, smdir, meddir, lgdir
Dim lwidth, lheight, aspectratio, newheight, newwidth, SaveFile, newPath
Dim filepath, DesiredWidth, DesiredHeight, quality, newfile, resizescale
Dim dy, dy1, dx, dx1, sx1, sx2, sy1, sy2
Dim swidth, sheight, sx1a, sx2a, sy1a, sy2a, sheighta, swidtha, blankspace
%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="../login.css">
<script src="js/admin.js" type="text/javascript" language="javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/scriptaculous.js" type="text/javascript"></script>
<script src="cropper/cropper.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
    function onEndCrop( coords, dimensions ) {
        $( 'x1' ).value = coords.x1;
        $( 'y1' ).value = coords.y1;
        $( 'x2' ).value = coords.x2;
        $( 'y2' ).value = coords.y2;
        $( 'width' ).value = dimensions.width;
        $( 'height' ).value = dimensions.height;
    }

    // with a supplied ratio
    Event.observe( 
        window, 
        'load', 
        function() { 
            new Cropper.Img( 
                'testImage', 
                { 
                    ratioDim: { x: 500, y: 500 }, 
                    displayOnInit: true, 
                    onEndCrop: onEndCrop 
                } 
            ) 
        } 
    );
</script>

<style type="text/css">
    input { 
        width: 40px;
    }

</style>

<script type="text/javascript">
(function() {

var img = document.getElementById('theImageToCrop').backgroundImage;
img.onload = function() {
    if(img.height > img.width) {
        img.height = '100%';
        img.width = 'auto';
    }
};

}());
</script>

<script>
function onSubmitForm() {
    var formDOMObj = document.frmSend;
    if (formDOMObj.attach1.value == "")
        alert("Please press the Browse button and pick a file.")
    else
        return true;
    return false;
}
</script>
<TITLE>Upload Listing Pics to the server</TITLE>
</HEAD>
<div style="padding:25px;">
    <form name="frmSend" method="POST" enctype="multipart/form-data" accept-charset="utf-8" action="testcropping.asp?" onSubmit="return onSubmitForm();">
    <Strong>Upload Image File to Server: </Strong>&nbsp; (Max Image Size per upload is 8 MB, Images will be resized)
    <br><br>
    <strong>1</strong>/ Choose an image &nbsp; <input id="attach1" name="attach1" type="file" size=60 style="width:390px;"><br>
    <br /> 
    <strong>2</strong>/ Position/zoom the crop box<font style="font-size:9px;"> (use mouse on corners to zoom, hold left mouse button and drag to move position)</font><br />
    <div style="width:512px; height:512px;"><div></div>
    <div id="theImageToCrop" align="center" style="background-image: url(../pics/No-Image.jpg); background-position:center; background-repeat:no-repeat; background-size:contain; max-height:512px; max-width:512px; width:100%; border: 1px solid #808080; position: relative;"><div></div>
        <div id="testWrap" style="height:512px; width:512px; text-align:center; vertical-align:middle;"><div></div>
            <img src="../cropper/tests/clear512px.png" src= alt="test image" id="testImage" style="width:100%;" />
        </div>
    </div>
</div>

<div style="padding-top:5px;">
        <label for="x1">x1:</label>
        <input type="text" name="x1" id="x1" />
        &nbsp;&nbsp; 
        <label for="y1">y1:</label>
        <input type="text" name="y1" id="y1" />
        &nbsp;&nbsp; 
        <label for="x2">x2:</label>
        <input type="text" name="x2" id="x2" />
        &nbsp;&nbsp; 
        <label for="y2">y2:</label>
        <input type="text" name="y2" id="y2" />
        &nbsp;&nbsp; 
        <label for="width">width:</label>
        <input type="text" name="width" id="width" />
        &nbsp;&nbsp; 
        <label for="height">height</label>
        <input type="text" name="height" id="height" />
</div>      
        <br /><strong>3</strong>/ Upload your image to server &nbsp; 

    <input style="margin-top:4px; background-color:#E9E9E9; width:150px;" type=submit value="Click here to Upload">
    </form>
    <br />
</div>
<script>
  function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object

    // Loop through the FileList and render image files as thumbnails.
    for (var i = 0, f; f = files[i]; i++) {

      // Only process image files.
      if (!f.type.match('image.*')) {
        continue;
      }

      var reader = new FileReader();

      // Closure to capture the file information.
          reader.onload = (function(theFile) {
        return function(e) {
          // Render thumbnail.
         var div0 = document.getElementById('theImageToCrop');
            div0.style.backgroundImage = "url(" + e.target.result + ")";
       };
      })(f);

      // Read in the image file as a data URL.
      reader.readAsDataURL(f);
    }
  }  

  document.getElementById('attach1').addEventListener('change', handleFileSelect, false);
</script>
</BODY>
</HTML>

I have the fiddle example for you to look at in different browsers(ff/ie/chrome/safari) here --> jsfiddle.net/FyJR3/3/

so in summary

if you open the fiddle in both Firefox and IE and when you select a local image - The Image does not disply in ie - but it does display in firefox - so i am looking to find a solution to this cross browser incompatability :) - also note it is NOT jQuery - it is prototype.js and scriptaculous.js - Thanks

هل كانت مفيدة؟

المحلول

Not an answer, just a short explanation: Internet Explorer < 10 does not support the File API, which you use when trying to get input.files[0]. So the type will never match, and the reader is never set (although I do believe the reader is also unsupported in IE). Unfortunately I am looking into a similar issue, most mentioned options are using flash or upload the image to a temp file.

IE support for Fiel API: http://caniuse.com/#search=file%20api

File API: http://www.w3.org/TR/FileAPI/

نصائح أخرى

The code you're using seem more complicated then it has to be. If you only need the user to load a single file then we don't have to loop over multiple files.

$('#file').on('change', function(evt){
    var file = evt.target.files[0];
    if(file.type.match('image.*')){
        var reader = new FileReader();
        reader.onload = (function(file){
            return function(e){
                $('#view').css({
                    'background-image': 'url(' + e.target.result +')'
                });
            }
        })(file);
    }

    reader.readAsDataURL(file);
})

try this fiddle

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top