2016-03-16 7 views
2

Я пытаюсь сделать две кнопки загрузки. Один для логотипа учетной записи.Несколько кнопок загрузки javascript только для размещения содержимого в одном

  .col-sm-6 
      .wrapper 
       Account Logo 
       #account_logo 
       = image_tag @account.logo.url, :class => 'account_logo' 
       = file_field_tag 'account[logo]', :accept => 'image/png,image/jpeg' 
       %a.btn.btn-default{:href => '#'} Choose file 
       %span.notice 
        Only PNG or JPG please. 

Другое для эмблемы электронной почты.

  .col-sm-6 
      .wrapper 
       Email Logo 
       #email_logo 
       = image_tag @account.email_logo.url, :class => 'email_logo' 
       = file_field_tag 'account[email_logo]', :accept => 'image/png,image/jpeg' 
       %a.btn.btn-default{:href => '#'} Choose file 
       %span.notice 
        Only PNG or JPG please. 

Я добавил javascript, чтобы он работал для обоих. Однако происходит что-то очень плохое. Я добавил предупреждения, чтобы попробовать и отлаживать, и они говорят мне, что все это происходит в #email_logo, даже когда я нажимаю кнопку #account_logo. Может ли какой-нибудь помощник javascript помочь мне?

   :javascript 
       var logo = ["#account_logo", "#email_logo"]; 

       for (var i = 0; i < logo.length; i++) { 
        var on_change = (logo[i] + ' input[type=file]'); 
        var on_click = (logo[i] + ' a.btn'); 
        var logo_img = (logo[i] + ' img'); 

        $(document).on('click', on_click , function() { 
        alert("it is now " + on_click); 
        $(on_change).click(); 
        alert("it is now " + on_change); 
        }); 
        $(document).on('change', on_change, function() { 
        alert("it is now " + on_change); 
        var filelist = $(this).get(0).files; 
        var reader = new FileReader(); 
        reader.onload = function (e) { 
         var url = e.target.result; 
         alert("it is now " + logo_img); 
         $(logo_img).attr('src', url); 
        } 
        reader.readAsDataURL(filelist[0]); 
        }); 
       } 
+0

Я подозреваю, что код "reader.readAsDataURL (filelist [0]);" который на третьей строке с конца вашей javascript программы. –

+0

@ fumu7 Почему? – alexia

ответ

1

Возможно, это связано с тем, что вы используете конструкцию цикла for(var i = ...) {} вместо logo.forEach(function(element) { ... }).

Причиной этого может происходить потому, что JavaScript не имеет блок определения объема, но функция обзорное означает, что ваша переменная i петля доступна во всей функции, и ваши .on('change', ...) обработчики будут относиться к этому i в качестве переменной, а не как независимо от значения, которое имела переменная при регистрации обработчика.

Попытайтесь использовать конструкцию logo.forEach(function(element) { ... }, и вместо того, чтобы устанавливать var on_change = (logo[i] + 'input[type=file]');, сделайте var on_change = (element + 'input[type=file]');.

+0

Спасибо! Проблема с областью была проблемой. Я изменил все свои 'logo [i]' на 'element' и изменил цикл for на' logo.forEach (function (element) 'и он работает. – alexia

+0

Поскольку я предполагаю, что ваш бэкэнд в рубине (из-за тега haml), возможно, я должен также упомянуть, что конструкция 'for' в ruby ​​также делает * not * вводит новую область, очень похожую на конструкцию' for' в javascript , поэтому циклы 'for' могут фактически привести к« интересным »проблемам в рубине. – Frost

0

Edit:

Ах-ха, @Frost нашел проблему - переменная сфера. Я бы сам использовал итератор и пропустил здесь область действия эффекта на привязку события.

Учитывая, что вы уже используете jQuery и, вероятно, после гораздо лучшей совместимости с браузером, чем forEach, я бы настоятельно рекомендовал использовать функцию jQuery.each. Вы можете также также встраивать массив логотипов, и передать событие щелчка непосредственно тоже дает:

$(["#account_logo", "#email_logo"]).each(function(logo) { 
    $(logo + " input[type=file]").on("click", $(logo + " a.btn").click); 
    // etc. 
}); 

Оригинальный ответ:

Это, кажется, как много кода не так много проблем описание. Вы говорите, что обработчики событий применяются к #email_logo, или что обе кнопки выполняют требуемое действие #email_logo? Я еще не делал загрузку файлов, но из краткого обзора логика выглядит нормально.

Было бы легче увидеть проблему, если вы использовали console.log, а не alert, и вставляли результаты здесь, а также описание того, как был создан журнал.

Я бы предпочел прокомментировать это, но у меня недостаточно репутации.