Slider FileReader JS Carga de imágenes múltiples (índice de aumento)

Estoy intentando crear un cargador de imágenes múltiples en JavaScript que cargue vistas previas de imágenes en un control deslizante, pero estoy teniendo algunos problemas. Hasta ahora parece que pude cargar las imágenes en el control deslizante, pero el problema parece ocurrir con mi variable i : cuando bash boostla, permanece igual, sin permitir que mis flechas deslizadoras previous y previous trabajando. Si alguien sabe cómo hacer que este control deslizante funcione correctamente, agradecería la ayuda.

Código JS:

 $('#_uploadImages').click(function() { $('#_imagesInput').click() }) $('#_imagesInput').on('change', function() { handleFileSelect(); }); function handleFileSelect() { //Check File API support if (window.File && window.FileList && window.FileReader) { var files = event.target.files; //FileList object var output = document.getElementById("frames"); for (var i = 0; i < files.length; i++) { var file = files[i]; //Only pics if (!file.type.match('image')) continue; var picReader = new FileReader(); picReader.addEventListener("load", function (event) { var picFile = event.target; console.log(event); current_i = i; prev_i = current_i - 1; next_i = current_i + 1; //var div = document.createElement("div"); //div.innerHTML = div.innerHTML + ""; //output.insertBefore(div, null); ////output.innerHTML = output.innerHTML + ""; // TODO: Enter Title output.innerHTML = output.innerHTML + '
  • ' + "" + '' + '
  • '; // TODO: Enter Title }); //Read the image picReader.readAsDataURL(file); } //output.innerHTML = output.innerHTML + '
  • ' + '
      ' + '
    • ' + '
    • ' + '
    • ' + '
    ' + '
  • ' } else { console.log("Your browser does not support File API"); } }

    JSFiddle: http://jsfiddle.net/Hybridx24/yfr57u6w/

    El problema con el código es que para cuando se ejecuta el evento de carga, el bucle for ya se ha incrementado. Entonces, si se agregan dos imágenes, el valor de i cuando el evento de carga se está ejecutando ya es 2.

    Una forma de resolver esto es agregar el valor de i a una matriz y recuperarlo en el detector de eventos uno por uno:

     var arrFilesCount = []; for (var i = 0; i < files.length; i++) { arrFilesCount.push(i); //push to array var file = files[i]; //Only pics if (!file.type.match('image')) continue; var picReader = new FileReader(); picReader.addEventListener("load", function (event) { var picFile = event.target; current_i = arrFilesCount.shift(); // get from array instead of using i prev_i = current_i - 1; next_i = current_i + 1; ... ... 

    JsFiddle correspondiente aquí


    Ahora, esta matriz también se puede usar para determinar el primer / último elemento y, por lo tanto, usarlo para pasar del último al primer elemento. Debido a que no podemos estar seguros de cuándo se ejecutará el detector de eventos (digamos si hay 100 imágenes que el primer detector de eventos puede ejecutar cuando el recuento del bucle ha alcanzado 5 o 10), entonces he usado dos bucles en lugar de uno. El primer bucle solo para poblar la matriz.

     var arrFilesCount = []; for (var i = 0; i < files.length; i++) { arrFilesCount.push(i); } 

    Permite usar esto para encontrar el primer y el último elemento

     current_i = arrFilesCount.shift(); if(current_i === 0){ prev_i = files.length - 1; //This is for the first element. The previous slide will be the last image. (i=length-1) } else{ prev_i = current_i - 1; } if(arrFilesCount.length === 0){ next_i = 0; //This is for the last element. The next slide will be the first image (i=0) } else{ next_i = current_i + 1; } 

    Vea este jsFiddle .


    Finalmente, puede haber situaciones en las que el usuario primero agrega un par de imágenes, luego vuelve a hacer clic en el botón de carga y agrega un par de imágenes más. En este caso, necesitamos corregir el href existente. Los elementos que debemos corregir son los next del último y prev primero. Esto se puede hacer usando:

     var start = $(output).find('li').length; var end = start+ files.length; if(start !== 0){ $(output).find('li > nav > a.prev').first().attr('href','#slide-' + (end-1)); $(output).find('li > nav > a.next').last().attr('href','#slide-'+start); } 

    Entonces, el jsFiddle final será algo como esto .

    Sustituido .append() para .innerHTML ; creado variable idx para incrementar .slide li elements id s; agregado evento click delegado para nav a elements; se agregó .bind() con this conjunto a picReader , pasé como parámetro al evento picReader onload ; agregado file.name al title atributo del elemento img ; navegación “punto” agregada con thumbnails de imágenes debajo de #frames ; title de la flecha de navegación

     var idx = -1, re = /(.*)(?=\.)/; $('#_uploadImages').click(function() { $('#_imagesInput').click(); }); $('#_imagesInput').on('change', function(event) { handleFileSelect(event); }); $(document).on("click", ".slider .slide nav a, .nav a", function(e) { e.preventDefault(); $(".slide").hide() .filter(":has(img[title^="+e.target.title.match(re)[0]+"])").show(); }); function handleFileSelect(event) { //Check File API support if (window.File && window.FileList && window.FileReader) { var files = event.target.files; //FileList object var output = document.getElementById("frames"); for (var i = 0; i < files.length; i++) { var file = files[i]; var picReader = new FileReader(); picReader.onload = function(index, event) { ++idx; var picFile = event.target; var slides = $(".slider li[id^=slide]"); // TODO: Enter Title $(output) .append('
  • ' + "" + '' + ''); // add title to `nav a` elements if (file.name === files[files.length - 1].name) { $(".nav").empty(); $("nav a").each(function(i, el) { if ($(el).closest("[id^=slide]").prev("[id^=slide]").length && $(el).is("nav a:nth-of-type(1)")) { $(el).attr("title", $(el).closest("[id^=slide]") .prev("[id^=slide]").find("img").attr("title") ) } if ($(el).closest("[id^=slide]").next("[id^=slide]").length && $(el).is("nav a:nth-of-type(2)")) { $(el).attr("title", $(el).closest("[id^=slide]") .next("[id^=slide]").find("img").attr("title") ) } if ($(el).is(".slider [id^=slide]:first a:first")) { $(el).attr("title", $("[id^=slide]:last").find("img").attr("title") ) } if ($(el).is(".slider [id^=slide]:last a:last")) { $(el).attr("title", $("[id^=slide]:first").find("img").attr("title") ) }; }); $(".slider img").each(function(i, el) { $(".nav").append( $("nav a[title^=" +$(el).attr("title").match(re)[0] +"]:first") .clone().html(el.outerHTML) ) }) } }.bind(picReader, i); //Read the image picReader.readAsDataURL(file); }; } else { console.log("Your browser does not support File API"); } }
  •  * { margin: 0; padding: 0; /*transition*/ -webkit-transition: all 1s ease; -moz-transition: all 1s ease; -o-transition: all 1s ease; transition: all 1s ease; } body { padding: 30px; } /* Slider */ .slider { height: 250px; left: 50%; margin: -125px -225px; position: absolute; top: 48%; width: 450px; /*box-shadow*/ -webkit-box-shadow: 0 0 5px #000; -moz-box-shadow: 0 0 5px #000; box-shadow: 0 0 5px #000; } .slider .frames { height: 250px; position: relative; list-style-type: none; } .slider .frames .slide { height: 250px; list-style: none; position: absolute; width: 450px; } .slider .slide:target { z-index: 100 } .slider .frames .slide img { height: 250px; width: 450px; } .slider .frames .slide nav a { background: hsla(0, 0%, 0%, .75); color: #fff; font-size: 16px; line-height: 50px; margin-top: -25px; opacity: 0; position: absolute; text-align: center; text-decoration: none; top: 50%; width: 50px; visibility: hidden; z-index: 10; } .slider:hover .frames .slide nav a { opacity: 1; visibility: visible; } .slider .slide nav a:hover { cursor: pointer; } .slider .frames .slide nav .prev { /*border-radius*/ -webkit-border-radius: 0 25px 25px 0; -moz-border-radius: 0 25px 25px 0; border-radius: 0 25px 25px 0; left: 0; } .slider .frames .slide nav .next { /*border-radius*/ -webkit-border-radius: 25px 0 0 25px; -moz-border-radius: 25px 0 0 25px; border-radius: 25px 0 0 25px; right: 0; } .slider .frames .slide nav a:hover { background: #000 } .slider .quicknav { bottom: 0; font-size: 0; opacity: 0; position: absolute; text-align: center; width: 100%; z-index: 100; } .slider:hover .quicknav { opacity: .9 } .slider .quicknav li { display: inline-block } .slider .quicknav a { background: hsla(0, 0%, 100%, .9); border: 1px solid hsla(0, 0%, 0%, .9); /*border-radius*/ -webkit-border-radius: 100%; -moz-border-radius: 100%; border-radius: 100%; display: block; height: 10px; margin: 10px 5px; text-decoration: none; width: 10px; } .slider .quicknav a:hover { background: hsla(0, 0%, 50%, .9) } .nav { width:100%; text-align:center; } .nav a { display:inline-block; background:transparent; border-radius:50%; border:4px solid transparent; width:24px; height:24px; margin:4px; } .nav a img { width:22px; height:22px; border-radius:50%; } .slider #one:target ~ .quicknav a[href="#one"], .slider #two:target ~ .quicknav a[href="#two"], .slider #three:target ~ .quicknav a[href="#three"], .slider #four:target ~ .quicknav a[href="#four"], .slider #five:target ~ .quicknav a[href="#five"] { background: hsla(0, 0%, 0%, .9); border-color: hsla(0, 0%, 100%, .9); background: rgb(244, 246, 245); /*linear-gradient*/ background: -webkit-gradient(linear, left top, left bottom, color-stop(rgba(244, 246, 245, 1), 0.01), color-stop(rgba(203, 219, 219, 1), 1), color-stop(rgba(216, 216, 216, 1), 1)); background: -webkit-linear-gradient(top, rgba(244, 246, 245, 1) 1%, rgba(203, 219, 219, 1) 100%, rgba(216, 216, 216, 1) 100%); background: -moz-linear-gradient(top, rgba(244, 246, 245, 1) 1%, rgba(203, 219, 219, 1) 100%, rgba(216, 216, 216, 1) 100%); background: -o-linear-gradient(top, rgba(244, 246, 245, 1) 1%, rgba(203, 219, 219, 1) 100%, rgba(216, 216, 216, 1) 100%); background: linear-gradient(top, rgba(244, 246, 245, 1) 1%, rgba(203, 219, 219, 1) 100%, rgba(216, 216, 216, 1) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(1%, rgba(244, 246, 245, 1)), color-stop(100%, rgba(203, 219, 219, 1)), color-stop(100%, rgba(216, 216, 216, 1))); background: -webkit-linear-gradient(top, rgba(244, 246, 245, 1) 1%, rgba(203, 219, 219, 1) 100%, rgba(216, 216, 216, 1) 100%); background: -moz-linear-gradient(top, rgba(244, 246, 245, 1) 1%, rgba(203, 219, 219, 1) 100%, rgba(216, 216, 216, 1) 100%); background: -o-linear-gradient(top, rgba(244, 246, 245, 1) 1%, rgba(203, 219, 219, 1) 100%, rgba(216, 216, 216, 1) 100%); background: linear-gradient(top, rgba(244, 246, 245, 1) 1%, rgba(203, 219, 219, 1) 100%, rgba(216, 216, 216, 1) 100%); filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#f4f6f5', endColorstr='#d8d8d8', GradientType=0); /*box-shadow*/ -webkit-box-shadow: inset 0 0 3px #000, 0 0 2px rgba(0, 0, 0, .5), 0 2px 3px #666; -moz-box-shadow: inset 0 0 3px #000, 0 0 2px rgba(0, 0, 0, .5), 0 2px 3px #666; }