0

I'm trying to load all the images inside a folder(I have more than 20K), to show them to users(just trying to build a page with images everywhere), on page load, using a JS inside my HTML. But I couldn't manage to load images. There is no error on web console also.

What's wrong with this code?

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>

    </head>

    <body>
        <script>               
        var folder = "images/";

        $.ajax({
            url : folder,
            success: function (data) {
                $(data).find("a").attr("href", function (i, val) {
                    if( val.match(/\.(jpe?g|png|gif)$/) ) { 
                        $("body").append( "<img src='"+ folder + val +"'>" );
                        } 
                    });
                }
            });
        </script>
    </body>
</html>

Also, other solutions without JS to achieve the same thing appreciated as well.

Thanks in advance.

Ferit
  • 8,692
  • 8
  • 34
  • 59
  • Perhaps your path is wrong. Try `/images` instead of `images/`. – Dennis Hackethal Feb 21 '16 at 01:30
  • What is in `data`? In most webservers, requesting a directory won't give you a JSON-encoded list of its contents – user70585 Feb 21 '16 at 01:31
  • @JohnDoe I used this answer for JS: http://stackoverflow.com/a/32940532/1079908. I'm not sure what that `data` is – Ferit Feb 21 '16 at 01:33
  • @Saibot requesting a directory on your webserver might get a different response than on the OP of that question did. – user70585 Feb 21 '16 at 01:36
  • @JohnDoe Maybe, I would appreciate another solution, if you have. – Ferit Feb 21 '16 at 02:06
  • @dchacke Nope, it's not about the folder name – Ferit Feb 21 '16 at 02:06
  • It's already clear you don't have server code supplying the data which you must have. You can't read a server directory from a browser ...for obvious good reasons – charlietfl Feb 21 '16 at 02:07
  • I'm the server. I'm running this HTML on my computer. – Ferit Feb 21 '16 at 02:08
  • But the html and javascript run in your browser and have no server access to read directories. That has to be done with server side programming language – charlietfl Feb 21 '16 at 02:09
  • OK, whats the solution then? – Ferit Feb 21 '16 at 02:09
  • What server language does server support?... use that to read directory and point ajax at that endpoint – charlietfl Feb 21 '16 at 02:17
  • I'm running Ubuntu. Maybe you can write an answer explaining the way to do it? – Ferit Feb 21 '16 at 02:27
  • but you have a server package running to be able to open url on `http://localhost` right? whatever language that server package supports is what you need to use. Or manually create a json file for now – charlietfl Feb 21 '16 at 02:34
  • The simplest solution would be to use `input type="file"` with `multiple` attribute set; at chromium / chrome could use `webkitdirectory` attribute to upload entire folder . Would first make sure folder contains only images. If all images have same file name , ending in a number , could use a loop to request each file name – guest271314 Feb 21 '16 at 02:36
  • @charlietfl I don't understand. Of couse I can open `localhost` url. This html is on my personal computer, and not in a virtual machine, I'm just playing with an HTML file to learn. – Ferit Feb 21 '16 at 02:41
  • @guest271314 Yeah maybe, but I don't have any clue how to do that, maybe you can write a detailed answer? – Ferit Feb 21 '16 at 02:42
  • as far as browser is concerned that is a server. WHatever server package you are using to enable localhost is what you need to read directory with and create an end point using a server side programming language. If it's WAMP or XAMP for example it would be php, or maybe you are using node.js to run server in which case use node to read it and create a route for that data – charlietfl Feb 21 '16 at 02:42
  • @Saibot See post. Note, only chromium / chrome support `directory` or `webkitdirectory` attributes; will need to select each image in folder for firefox, ie, etc.; though `multiple` should allow this – guest271314 Feb 21 '16 at 02:48

4 Answers4

1

Try using input type="file" with multiple and webkitdirectory , attributes set, accepts attribute set to "image/*" , .change(), for loop , IIFE to create a closure within for loop, URL.createObjectURL()

$(":file").change(function(event) {
  var files = this.files;
  for (var i = 0; i < files.length; i++) {
    (function(n) {
      var img = new Image;
      img.onload = function() {
        $("body").append(this)
      }
      img.src = window.URL.createObjectURL(files[n])
    }(i))
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<input type="file" accepts="image/*" multiple webkitdirectory />
guest271314
  • 1
  • 15
  • 104
  • 177
  • Nice answer, thanks. But what I want is to load all images from a folder when the page loads, to show them to users. Your example is to post images from folder. I think you misunderstood me. – Ferit Feb 21 '16 at 02:52
  • @Saibot Do all images have similar file name ? Even if they do not, you could compile a list of file names and use `$.ajax()` to load each file, in succession, into `document` . At `terminal` you could use `$ cd ~/path/to/folder` , `$ ls` to list all files in folder `/path/to/folder` . Once you have the list of files, you can create an array of file names for use with `$.ajax()` – guest271314 Feb 21 '16 at 02:54
  • I can write a script to name all the images like 1, 2, 3 etc. that's no problem. Can you show an example, assuming I have a filename list? – Ferit Feb 21 '16 at 02:58
  • Yes, will post another solution – guest271314 Feb 21 '16 at 02:58
1

Prerequisite: Adjust chromium / chrome launcher to add required flag , e.g.; chromium-browser --allow-file-access-from-files or google-chromne --allow-file-access-from-files ; see How do I make the Google Chrome flag "--allow-file-access-from-files" permanent?

html, having number of img elements equal to image files in folder

<!-- note , `src` attribute not included -->
<img class="image" style="opacity:0.0" alt="1">
<img class="image" style="opacity:0.0" alt="1a">
<img class="image" style="opacity:0.0" alt="1b">
<img class="image" style="opacity:0.0" alt="1c">

You should then be able to use approach described at Preloading images in HTML to iterate an array of image file names to load multiple images in succession.


Using XMLHttpRequest() with responseType set to Blob , URL.createObjectURL , new Promise() constructor , Promise.all()

var arr = ["file:///home/user/path/to/image/file-1"
          , "file:///home/user/path/to/image/file-2"];

function loadImages(src) {
  return new Promise(function(resolve, reject) {
    var request = new XMLHttpRequest();
    request.onload = function() {
      $("<img/>", {
        src: URL.createObjectURL(this.response)
      }).on("error", reject)
      .appendTo("body");
      resolve(src + " loaded")
    }
    request.onerror = reject;
    request.open("GET", src);
    request.responseType = "blob";
    request.send(); 
  }) 
}  

Promise.all(arr.map(function(src) {
  return loadImages(src)
}))
.then(function(data) {
   console.log(data)
}, function(err) {
   console.log("error", err)
})

See also jquery-ajax-native which allows Blob or ArrayBuffer to be returned from jQuery.ajax()

$.ajax({
    dataType: 'native',
    url: "file:///home/user/path/to/image/file",
    xhrFields: {
      responseType: "blob"
    }
})
.then(function(data) {
  $("<img/>").attr("src", URL.createObjectURL(data))
  .appendTo("body")
})
Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177
  • Thanks for answer. But as far as I understand, I need to have a `var arr` array size equals to image number, also equal number of ` – Ferit Feb 21 '16 at 13:07
  • @Saibot The initial premise of original Question was that you were performing these actions locally ? Not on a website that was live on web. That is why included portion about allowing local access to files using a flag at chromium , chrome to use `$.ajax()` locally. The `img` elements can be dynamically created instead of written in the `html` document. _"I can write a script to name all the images like 1, 2, 3 etc. that's no problem."_ , _"But I have more than 20K images, and this is not practical."_ Whether 20 images or 20k images should not affect process. – guest271314 Feb 21 '16 at 16:44
  • Maybe I don't get what you explain, I have to study these things for a while. Thanks anyway, upvoting your answer. – Ferit Feb 21 '16 at 17:29
1

In the code listed above, theres no way you are getting anything in the data that is being returned in ajax as url:"images/" is a folder. You would need to set the url to something that supplies the list of paths of the respective files like a json response:

{1:"images/abc.jpg",2:"images/abc.jpg"}

OR

{imagelinks:["images/abc.jpg","images/abc.jpg"]}

Then you can supply these text path to the image sources on page.

  • Problem is, it is too impractical if you have 20k images. – Ferit Feb 21 '16 at 14:44
  • Wait wait, you mean I have to prepare a directory list, and use that list in the function? – Ferit Feb 21 '16 at 15:00
  • Yes a directory list or something on these lines on server side. You can also refer: http://stackoverflow.com/questions/6994212/is-there-a-way-to-return-a-list-of-all-the-image-file-names-from-a-folder-using – PARDEEP BALOWRIA Feb 21 '16 at 18:11
0

The inclusion of "folder" when you append creates a redundancy in the file paths. Remove that and it works great:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
</head>
<body>
    <script>               
    var folder = "images/";

    $.ajax({
        url : folder,
        success: function (data) {
            $(data).find("a").attr("href", function (i, val) {
                if( val.match(/\.(jpe?g|png|gif)$/) ) { 
                    $("body").append( "<img src='" + val +"'>" );
                    } 
                });
            }
        });
    </script>
</body>
</html>
Anna
  • 28
  • 5