Доброго времени суток, мой дорогой друг. В сети, да и на Хабре, есть множество статей на тему создания своего input type=«file», но все они отличаются большим количеством костылей и большим количеством кода, что, как мне кажется, не есть хорошо. Ибо, как бы это не было парадоксально, меньше — лучше.



Рабочий пример того, что получится:



Сам принцип кастомизированного input file особых отличий не имеет: убираем с экрана input, и всё возлагаем на плечи label, которому мы добавим свои стили. Главное отличие — малое кол-во кода.

Начнём

Мы имеем input и label:

<label for="myfile" class="label">Выберите файлы</label>
<input type="file" class="my" id="myfile" name="myfile" multiple>

Теперь уберём с экрана input, добавив классу my следующие стили:

.my {
  width: 0.1px;
  height: 0.1px;
  opacity: 0;
  overflow: hidden;
  position: absolute;
  z-index: -1;
}

А также стилизуем сам label, добавив ему свои стили:

.label {
    width: 180px;
    height: 50px;
    border-radius: 4px;
    text-align: center;
    cursor: pointer;
    display: block;
    font: 14px/50px Tahoma;
    transition: all 0.18s ease-in-out;
    border: 1px solid #333;
    color: #333;
}

.label:hover {
    color: white;
    background: #333;
}

И теперь самое интересное: javascript. Собственно вот он:

$('.my').change(function() {
    if ($(this).val() != '') $(this).prev().text('Выбрано файлов: ' + $(this)[0].files.length);
    else $(this).prev().text('Выберите файлы');
});

Он работает следующим образом: Когда пользователь жмёт на input с классом .my, то js начинает отслеживать его изменение. Дальше в дело вступает if (если). Так вот если у нас этот (this) input не пустой (то есть файл был какой-то выбран), то стоящий по соседству выше элемент (это у нас label) получит текст «Выбрано файлов» + кол-во файлов, которое выбрал пользователь. Ну а если пользователь ничего не выбрал, то label просто получит текст «Выберите файлы».

Всё!

// Дополнительная информация

Может возникнуть проблема с вёрсткой, какая была и у меня. А проблема может заключаться с этим пресловутым .prev(). По факту, есть вероятность того, что невозможно расположить label и input file рядом друг с другом, и текст «Выбрано файлов» будет применяется не к label, а к левому элементу.

Эту проблему можно решить вот так:

Поместите label и input в один div, и дайте этому div'у класс, к примеру «box-form»

<div class="box-form">
<p>Текст какой-то</p>
<div>
<label for="myfile" class="label">Выберите файлы</label>
</div>
<div>
<div></div>
<input type="file" class="my" id="myfile" name="myfile" multiple>
</div>
</div>

И замените в js

$(this).prev() 

на

$(this).closest('.box-form').children('.label')

Вуаля! Теперь, стоявшие далеко друг от друга, label и input способны взаимодействовать друг с другом.

Лучше, конечно, избегать таких случаев, но никто не защищён от фреймворков, где input'ы пишешь не ты, а их генерирует сам фреймворк…

Спасибо за внимание.
Поделиться с друзьями
-->

Комментарии (46)


  1. Delphinum
    06.02.2017 13:56
    +20

    А разве зависимость в виде JQuery уже считается минималистичным решением?


    1. Azoh
      06.02.2017 14:16
      +1

      Конечно же. В хабах же jQuery, а не Javascript. Для настоящих jQuery-программистов.


      1. MrCheater
        06.02.2017 16:21
        +8

        Не просто jQuery, а jqyery


        jqyery

        jqyery


        1. kirigosh
          06.02.2017 21:21
          -1

          ахаха))) спасибо, не заметил) новый язык, получается, изобрёл.
          А по поводу зависимости. Сейчас на практике 99% сайтов используют jquery. Зачем сопротивляться тенденции?


          1. raveclassic
            06.02.2017 21:52
            +3

            Видимо, 99% вашей практики? И ради чего, пару раз DOM пощупать?


            1. kirigosh
              06.02.2017 22:02
              -2

              DOM пощупать, анимацию поцеловать, ajax по попе шлёпнуть и promise подмигнуть.


              1. raveclassic
                06.02.2017 22:08
                +3

                А что не так со стандартным API? Нет, ну я понимаю, в 2010 jquery из всех щелей лезла. Но ведь 2017 на дворе, все API давно стандартизировано.


    1. Rad1calDreamer
      06.02.2017 14:39
      +2

      Любой пост, начинающийся с «Пишем самый простой\крутой\быстрый %имяФичи%....» содержит в себе jQuery. И лучше не спрашивать: «А с какой целью вы здесь используете jQuery? »


      1. saluev
        06.02.2017 14:55
        +28

        Моя любимая часть — $(this)[0].


  1. k12th
    06.02.2017 15:01
    +3

    Если label не содержит в себе input, то он и не будет работать как лейбл. То есть, нужен id у инпута и for у этого лейбла. И если верстка не совсем кривая, то найти нужный лейбл можно через $('label[for=" + this.id + '"]').


  1. keslo
    06.02.2017 15:41
    +1

    Быстро-то, может быстро. Но разбираться с «быстрым» кодом потом дольше приходится.

    Как по мне, если вы работаете с несколькими дочерними узлами внутри родительского, то можно использовать всплытие событий. И не использовать parent() и всякую другую вакханалию.

    $('.dada').on('change', function(e) {
        if(e.target.className === 'my') {
            var files = e.target.files.length;
            var text = files ? 'Выбрано файлов: ' +files : 'Выберите файл';
      	$(this).find('label').text(text);
        }
    })
    

    Пример https://jsfiddle.net/keslo/07bupmgp/


  1. Aingis
    06.02.2017 16:52
    +18

    Кажется, любой здешний обитатель может написать код лучше.


    Судя по кусочку { width: 0.1px; height: 0.1px; opacity: 0;...}, вы читали статью Styling & Customizing File Inputs the Smart Way (которая находится по первым же ссылкам в поиске), но не дочитали даже до раздела «Keyboard Navigation». А зря, там учтено много нюансов. Вы бы хоть список требований составили.


    Вот, например, какие есть серьёзные недостатки:


    • Нет отображения фокуса.
    • Не работает драг-энд-дроп.
    • Нет поддержки доступности (речевые технологии, тач-устройства, пульт телевизора).
    • Не отображается имя загруженного файла.
    • Нет отображения ошибок (неверный формат файла, слишком большой размер).
    • Захардкоженные строки текста. Будут трудности с переводом.
    • Негибкая вёрстка.
    • Грубые ошибки вёрстки (захардкоженный размер кнопки, не указано семейство шрифтов, не указан цвет фона, неконтрастный текст, transition: all).
    • Лишняя зависимость от jQuery, когда в ней нет никакой острой необходимости.
    • Не работает при выключенном (сломанном) яваскрипте.

    А какие проблемы вы решали?


    1. dif
      06.02.2017 19:24
      +3

      Ох. Посмотрел по вашей ссылке свою «статью», которую написал 4 года назад — теперь не могу развидеть этот кривой CSS и говнокод на jQuery :(

      Спасибо, что напомнили — обязательно перепишу это безобразие с гордой пометкой «tutorial», как появится время.


    1. kirigosh
      06.02.2017 22:59
      -5

      Нет отображения фокуса.


      Не работает драг-энд-дроп.

      Поле для drag&drop нужно делать, а не на кнопку кидать. Кидать на кнопку — это уже маразм какой-то…
      Нет поддержки доступности (речевые технологии, тач-устройства, пульт телевизора).

      Речевые?.. Вообще никак не знаком с этим. Как обычный input file с помощью речевых открыть?
      Тач? Он не будет работать? Пальцем не попадёшь или что?
      Телевизор? Меня интересует сейчас не поддержка телевизоров, а хранилище, с которого будут загружаться файлы. Тебе, как минимум, нужна флешка. Ситуация, наверно, будет такая: Ты идёшь к компу и скидываешь на флешку файлы, достаёшь из компа флешку и идёшь к телевизору, вставляешь её (а usb вход находится сзади, и тебе нужно еще попотеть, чтобы эту флешку вставить) в телевизор, и начинаешь тыкать пультом по форме… Товарищ, я смотрю вы знаете толк в извращениях. Хотя, я наверно не прав. Я подумаю на счёт этого…
      Не отображается имя загруженного файла.

      Как будто надо. Ты еще попроси превью изображения с функцией перетаскивания… Наша цель: быстро и просто.
      Нет отображения ошибок (неверный формат файла, слишком большой размер).

      Ну это не моя забота. Для проверки формы пишется отдельная функция, которая меня не касается, и разработчик её расширяет так, как ему вздумается. К примеру, у меня валидацию устраивает yii, и все у меня ошибки нормально отображаются.
      Захардкоженные строки текста. Будут трудности с переводом.

      На другой язык? Трудности… Трудности будут также для людей с ограниченными возможностями, для детей и для стариков. О каком переводе идёт речь? Для разных языков нужно писать разные сайты с нуля, придерживаясь законам основного дизайна. Писать один и тот же код для нескольких языков тоже самое, что делать резиновые сайты.
      Негибкая вёрстка.
      Грубые ошибки вёрстки (захардкоженный размер кнопки, не указано семейство шрифтов, не указан цвет фона,

      Размер кнопки надо было в процентах указывать?
      Слово Tahoma просто так написано? Для красоты?
      Цвет фона указан. Он прозрачный.
      Вот блин, цвет не контрастный. Чтож теперь делать? Этож обязательное правильно: использовать зелёный цвет. Иначе же форма работать не будет.
      transition: all и? Что не так?
      Лишняя зависимость от jQuery, когда в ней нет никакой острой необходимости.

      Наличие формы, как бы уже подразумевает наличие jquery. Писать на голом javascript тоже самое, что купить машину и ходить пешком.
      Не работает при выключенном (сломанном) яваскрипте.

      Если яваскрипт у юзверя сломан, то он до моего input file даже не дойдёт. так что тут мне не о чем переживать.

      А какие проблемы вы решали?

      Внешний вид. На разных браузерах input кроме того, что страшный, так еще и везде разный. Хотелось бы придерживаться основному стилю/дизайну при разработке.


      1. raveclassic
        06.02.2017 23:13

        К примеру, у меня валидацию устраивает yii, и все у меня ошибки нормально отображаются.
        Я знал! Я знал!


      1. herr_kaizer
        06.02.2017 23:23
        +3

        это уже маразм какой-то
        Маразм — это то, что вы решили, что убирать стандартное поведение — это хорошая идея.

        Как будто надо.
        Ну это вообще пушка. Хорошо, таких как вы меньшинство, по крайней мере на крупных ресурсах.

        Писать один и тот же код для нескольких языков тоже самое, что делать резиновые сайты.
        Это даже комментировать не хочется.

        Сколько вам лет?


        1. kirigosh
          06.02.2017 23:41
          +1

          20


      1. jhekasoft
        07.02.2017 01:47
        +1

        О каком переводе идёт речь? Для разных языков нужно писать разные сайты с нуля, придерживаясь законам основного дизайна. Писать один и тот же код для нескольких языков тоже самое, что делать резиновые сайты.


        Неадекватно.


      1. Aingis
        07.02.2017 11:24

        Я смотрю, вы специалист по говнокоду.


      1. michael_vostrikov
        07.02.2017 12:54

        > Захардкоженные строки текста. Будут трудности с переводом.

        На другой язык? Трудности… Трудности будут также для людей с ограниченными возможностями, для детей и для стариков.

        Указанные вами трудности связаны с физическими возможностями и знаниями пользователей. А вам говорят про трудности при разработке и поддержке.


        Для разных языков нужно писать разные сайты с нуля, придерживаясь законам основного дизайна.

        Вы в курсе, что копи-паста это плохой подход к проектированию? Как потом это все поддерживать? Да и зачем тратить столько времени и сил, когда есть способы гораздо проще.


        Размер кнопки надо было в процентах указывать?

        Не надо было его вообще указывать. Чтобы другому программисту не пришлось переопределять его в 10 местах, если понадобилось размер шрифта увеличить или текст подлиннее написать.
        На немецком, например, эта надпись в 1.5 раза длиннее. Как вы предлагаете придерживаться законов основного дизайна? Руками размер каждой кнопки задавать, чтобы внутренние отступы нормально выглядели? Или проще все-таки отступы стандартными средствами задать?


        Наличие формы, как бы уже подразумевает наличие jquery.

        Ничего подобного. Это конкретно в Yii работа с полями формы происходит через jQuery.


  1. ilyaplot
    06.02.2017 18:13

    jsfiddle за пару минут стало лучше. Но это самый минимум того, что нужно было сделать.


    1. keslo
      06.02.2017 18:35

      Ну там много, что можно изменить :-)
      Получилась бы хорошая задачка для собеседования, типа «что бы вы изменили в этом коде и почему?».


    1. kirigosh
      06.02.2017 21:56
      -3

      вторая часть комментария вас тоже касается https://habrahabr.ru/post/321250/#comment_10055500


  1. 0Ilya
    06.02.2017 21:31

    Почему статью написал он, а стыдно мне?

    Какое удобное название классов, какой универсальный обработчик и код!

    Вот самое простейшее улучшение данного кода:


    1. kirigosh
      06.02.2017 21:51
      -9

      Сейчас мне стыдно за ваш код. Я, конечно, профан в разработке, но поясните мне: на кой черт нужен var text_label_id = $(this).attr('id');? Мы все знаем, что var используют для обозначения того, или иного куска кода. Чтобы этот кусок стал короче и более понятен, мы используем var. Особенно он полезен, когда этот кусок кода встречается неоднократно, то объявление переменной — просто спасение. Но здесь… Здесь что-то новенькое. Вы только один раз использовали text_label_id, и сделали это, между прочем, на соседней строчке. И самое смешное, что вы дали ему название, которое по своей длине не особо-то и отличается от первоначального источника… $(this).attr('id'); = 19 символов. text_label_id = 13 символов. Оно того стоило?

      А теперь поговорим про скорость, мой всё еще не менее дорогой друг.
      Что быстрее .prev() или label[for="(this).attr('id')"]? Ну вот серьёзно, представь, что проще сделать?
      Давай я для тебя аналогию проведу, а то, мне кажется, ты сразу не поймёшь мою мысль.
      Вот смотри: допустим ты живёшь на 50-ом этаже многоэтажного дома. В квартире, к примеру, 297. И вот тебе по срочной необходимости понадобилась соль. Да, банальная такая соль. Ты знаешь, что соль может дать тебе твой сосед Вася, который живёт в соседней квартире на площадке твоего этажа, но номер квартиры забыл и посчитать не можешь. Но так как ты у нас очень педантичный человек, тебе обязательно нужно знать номер квартиры. И что делаешь ты? Ты выходишь из своей квартиры, спускаешься на первый этаж и начинаешь заходить во все квартиры, проверяя, живёт ли в этой квартире Вася. «Вася тут?» — обращаешься ты к жильцу квартиры номер 1. И так далее. Каждую, мать её, квартиру проверяешь. И потом уже, под вечер, когда ты дошел до 298 квартиры, где живёт наш Вася, ты просишь у него соль. Красаучик, ничего не сказать.
      Вот и label[for="(this).attr('id')"] тоже самое. Начинаешь перебирать весь документ, в надежде найти label, у которого id равен id input. Ключевое слово, если ты не понял, здесь «весь документ».


      1. raveclassic
        06.02.2017 22:00
        +3

        Переменная нужна для простоты поддержки, а не для экономии на спичках символах.

        С чего вы взяли, что поиск по селектору осуществляется перебором?

        Что будет, если между инпутом и лэйблом добавится элемент?

        Можете переписать это на DOM API? Вы удивитесь, насколько бесполезен тут jquery.


        1. kirigosh
          06.02.2017 22:24
          -10

          так я описал случай, когда между ними появляется еще один элемент. Мы обращаемся к родителю и у родителя, в дочках, ищем label. Всё просто.
          А с чего вы взяли что это не перебор файла? Компьютер сразу знает, где у него находится label for=«id=input»? Ну ка, вспомни, как у тебя на компьютере работает поиск? Так я тебе напомню. Берётся название файла и проверяется это название с файлами на компьютере. Так и тут. Берётся документ (html) и проверяются все строчки на совпадение. Ты ради интереса создай web файл, который будет весить 1гб. И сделай потом label[for="(this).attr('id')"]. Зависло? Странно… Не должно…
          Ты можешь сказать, что я утрирую, и что по факту у нас не будет документа в 1гб, и что разницы мы не ощутим между prev() и label for=«id=input», но хочу тебе сказать, а ты это тоже забыл. 100 рублей = 100 раз по 1 рублю. Так вот задержка в 1/100, которую мы, якобы, не ощутим, добавится к другим задержкам, что приведёт потом к тому, что мы тупо сидим и ждём, пока у нас комп сообразит, ибо таких обращений, типа abel for=«id=input», у нас немерено. А потом мы виним железо в зависаниях, виним хром, который много памяти жрёт, виним то, чего винить не должны. Ты не говнокодь, тогда нормально всё будет! Глюков не будет. Или другое сравнение: игры требовательны к железу. Они не требовательны, они просто не оптимизированы.Я на 1000% уверен, что можно оптимизировать любую игру и играть в неё на максимальных настройках графики на старом ПК 2004 года. А из-за таких, как ты, у нас всё на говне и держится. Всё лагает, зависает и требует ОЗУ.
          На моём старом пк full HD видео на youtube лагает, просто fps падает. Видимо youtube писали такие, как ты… Спасибо тебе за web 2.0


          1. Aingis
            06.02.2017 22:42
            +2

            Это просто шедевральный комментарий!


            Ты можешь сказать, что я утрирую, и что по факту у нас не будет документа в 1гб, и что разницы мы не ощутим между prev() и label for=«id=input», но хочу тебе сказать, а ты это тоже забыл. 100 рублей = 100 раз по 1 рублю. Так вот задержка в 1/100, которую мы, якобы, не ощутим, добавится к другим задержкам, что приведёт потом к тому, что мы тупо сидим и ждём, пока у нас комп сообразит, ибо таких обращений, типа abel for=«id=input», у нас немерено. А потом мы виним железо в зависаниях, виним хром, который много памяти жрёт, виним то, чего винить не должны. Ты не говнокодь, тогда нормально всё будет! Глюков не будет. Или другое сравнение: игры требовательны к железу. Они не требовательны, они просто не оптимизированы.Я на 1000% уверен, что можно оптимизировать любую игру и играть в неё на максимальных настройках графики на старом ПК 2004 года. А из-за таких, как ты, у нас всё на говне и держится. Всё лагает, зависает и требует ОЗУ.


          1. raveclassic
            06.02.2017 22:51
            +1

            Потрясающе! Жаль вашего работодателя.


            1. melnik909
              07.02.2017 11:23

              Вы все же перегибаете палку. Мальчишка еще учится. Да, его решение далеко от совершенства, но и говорить так, тоже не стоит. Вспомните себя в 20. Нужно меньше негатива и больше конструктивной критики.


              1. raveclassic
                07.02.2017 12:10

                Понятное дело, перегибаю. Это тоже часть процесса обучения, так сказать, получить по шапке, чтобы впредь думать, что писать.
                Серьезно, без обид, все мы шли этим путем, но не все позволяли себе что-то из разряда вышеизложенного.


          1. yarosroman
            07.02.2017 02:17
            +5

            В 20 лет то, уже пора перестать обижаться на конструктивную критику и начать анализировать, что вам говорят.


          1. DjOnline
            07.02.2017 14:04

            Позвольте присоедениться к срачу! :)
            Веб-видео (Youtube и другие) действительно тормозит и через html5, и через flash на старом железе, которое тем не менее способно тянуть это видео через MPC и LavFilters/CoreAvc, в виду того что браузер всё таки не полноценный оптимизированный видеоплеер, и не знает таких штук как внешние быстрые кодеки, decode frame in advance и прочей специфики. Внешние декодеры на старом железе — это не пустое слово, некоторые из них заточены под старые intel адаптеры и умеют частично использовать аппаратное ускорение, которое недоступно через html5/flash, потому что системный декодер (либо встроенный в браузер) не поддерживает это железо и считает устаревшим.
            Пример перед глазами — двухядерный ноутбук с Intel 3100MHD, который без проблем показывает в MPC или Kodi 1080/24p, но в ютубе даже 720p притормаживает что в Flash что в html5. Также это заметно на старых атомных планшетах, для которых не всегда есть поддержка аппаратного декодера в браузере/системе.
            Помню были такие плагины, которые меняют содержимое flash/html5 плеера на embed vlc/wmp и видео начинает идти стабильнее на старых машинах. Пример — https://chrome.google.com/webstore/detail/vlc-4-youtube-beta/jldiailifbdkepgpcojllmkbakleicab?hl=en, или https://addons.mozilla.org/en-US/firefox/addon/mpc-yt/ для MPC.


            1. raveclassic
              07.02.2017 14:25

              Позвольте присоедениться к срачу! :)
              А давайте!

              Ну как же, проблема же не в кодеках, железе, прожорливой технологии, оптимизации или в чем-то там еще. Проблема в том, что мы с вами тут только и делаем, что говнокодим и, вообще, ломаем веб, негодяи. Все же просто.


            1. Aingis
              07.02.2017 16:56

              Ну, на Ютюбе 1080p60fps тормозит даже на довольно мощных системах. А причина в том, что Ютюб очень любит использовать кодек VP9, который сжимает немного лучше, но ценой того, что аппаратно его никто не умеет декодировать. В таком случае очень помогает расширение вроде h264fy, благодаря переключению на кодек h264.


              1. DjOnline
                08.02.2017 19:06

                Описываемые события были задолго до появления 1080/60p и vp9 на youtube, и наблюдаются по сей день на 1080/24p или даже 720/24p. Не хочу повторяться, многие старые массовые видеоадаптеры intel умеют аппаратное декодирование через стороннии кодеки, но не умеют через системные и через браузер. На ещё более старых системах без аппаратного декодирования проблема в том же, в браузер/flash встроен ffmpeg, который не является образцом скорости, в отличи например от старых добрых CoreAvc/LavFilters. Опять же видеоплеер умеет выводить видео через EVR и прочее, а браузер должен делать куча других вещей, composition и прочее, предусмотреть отображение html элементов поверх видео, что тоже не прибавляет скорости. Поэтому даже массовый intel 4500Mhd 2008 года, который без проблем тянет в MPC 1080/24p, неспособен в youtube воспроизвести 1080/24p.


      1. michael_vostrikov
        07.02.2017 19:00
        +1

        Но здесь… Здесь что-то новенькое.

        Это для вас новенькое. Переменные вводятся для понятности и упрощения поддержки.

        А теперь поговорим про скорость

        А вот поговорим. Что быстрее, обращение к элементу напрямую средствами браузера или через дополнительную библиотеку, которая обращается к нему средствами браузера? Ну вот серьёзно, представьте, что проще сделать? Давайте я для вас аналогию проведу, а то, мне кажется, вы сразу не поймёте мою мысль.

        Допустим, вам по срочной необходимости понадобилась соль. Да, банальная такая соль. Вы знаете, что соль может дать ваш сосед Вася, который живёт в соседней квартире на площадке вашего этажа. Но вы не хотите просто зайти к нему и попросить. Вы звоните своему юристу, просите его «найди Васю и спроси у него соль», он ищет адрес Васи в городской базе данных, приезжает к нему, составляет договор, берет соль, заворачивает ее в пакет, передает вам, вы разворачиваете пакет и берете соль. Зато вы точно знаете, что юрист решит все вопросы сам — и присутствие/отсутствие Васи и наличие у него соли.

        К чему это я? К тому, что если вы используете jQuery, то нет смысла экономить на селекторах, тем более для одного нажатия, тем более в таком эмоциональном ключе. Все равно это будет медленнее варианта без jQuery. Хотите скорости — пишите на чистом javascript.

        Я, конечно, не специалист в тестировании, но вот вам небольшой тест производительности.
        Скрытый текст
        <!DOCTYPE html>
        <html>
            <head>
                <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
            </head>
        
            <body>
                <div id="container" style="display: none"></div>
        
                <script>
                    $(document).ready(function() {
        
                        createHtml();
        
                        var t0 = performance.now();
                        testJQuery();
                        var t1 = performance.now();
                        console.log("testSelector() time: " + (t1 - t0) + " ms.");
        
                        var t0 = performance.now();
                        testNative();
                        var t1 = performance.now();
                        console.log("testNative() time: " + (t1 - t0) + " ms.");
        
        
        
                        function createHtml()
                        {
                            var html = '';
                            for (var i = 0; i < 1000; i++) {
                                html += '<label for="id_'+i+'">' + i + '</label>' +
                                        '<input type="file" id="id_'+i+'"/>';
                            }
                            $('#container').html(html);
                        }
        
                        function testJQuery()
                        {
                            var max = 1000, min = 0;
                            var payload = 0;
                            for (var i = 0; i < 100000; i++) {
                                var id = Math.floor(Math.random() * (max - min)) + min;
        
                                var $input = $('#id_'+ id);
                                payload += $input.prev().html().length;
                            }
                            console.log(payload);
                        }
        
                        function testNative()
                        {
                            var max = 1000, min = 0;
                            var payload = 0;
                            for (var i = 0; i < 100000; i++) {
                                var id = Math.floor(Math.random() * (max - min)) + min;
        
                                var input = document.querySelector('#id_'+ id);
                                payload += input.previousSibling.innerHTML.length;
                            }
                            console.log(payload);
                        }
                    });
                </script>
            </body>
        </html>
        


        1. Aingis
          07.02.2017 19:28

          100000 повторов с рэндомом — не очень хорошая идея. Думаю, реально jQuery отстаёт ещё больше, так как элементов всего 1000 и результат кешируется. Из-за этого на повторах смазываются затраты времени парсинга селектора. 1000 повторов, кстати, вполне хватит. performance.now() меряет с точностью до 1/1000 мс.


      1. rayz_razko
        08.02.2017 10:31

        Вам будет полезно почитать это: Clean Code by Robert C. Martin


    1. AiZen_13
      07.02.2017 09:37
      +1

      Не сочтите за критику, но зачем Вам jQuery для получения id и files?
      Намного ж изящнее и проще использовать this.id и this.files
      библиотека отличная конечно, но порой ее суют куда не попадя — какое-то #жиквериголовногомозга прям


  1. di-strange
    06.02.2017 23:01

    Не так красиво, но все таки без jQuery


  1. vlfesko
    06.02.2017 23:01

    А как же быть с фокусом? Я, конечно, все понимаю, но TAB никто не отменял — иногда проще и быстрее доклацать до инпута табом, если постоянно пользуешься страницей.


  1. AiZen_13
    06.02.2017 23:01
    +1

    сдается мне, можно выкинуть стили height, width, overflow для класса .my, а то что-то кода многовато


  1. Ivanq
    06.02.2017 23:01

    $(this).val()
    $(this).prev().val("...")

    А без jQuery слабо? Было бы прекрасное решение, если бы использовать Vanilla JS.
    
    document.querySelector('.my').addEventListener('change', function(e) {
        if (e.target.value != '') e.target.previousSibling.innerHTML = 'Выбрано файлов: ' + e.target.files.length;
        else e.target.previousSibling.innerHTML = 'Выберите файлы';
    });


  1. herr_kaizer
    06.02.2017 23:09
    +1

    Ну что за жесть, могли бы хоть как плагин оформить. Будто на 5 лет назад во времени переместился.

    Мне пару часов назад хабр показывал рекламу «Стань программистом за 2 часа», видимо примерно этого уровня оттуда выходят.


  1. iwonz
    07.02.2017 12:20
    -2