Comments 48
Конечно же. В хабах же jQuery, а не Javascript. Для настоящих jQuery-программистов.
Не просто jQuery, а jqyery
А по поводу зависимости. Сейчас на практике 99% сайтов используют jquery. Зачем сопротивляться тенденции?
Если label
не содержит в себе input
, то он и не будет работать как лейбл. То есть, нужен id у инпута и for у этого лейбла. И если верстка не совсем кривая, то найти нужный лейбл можно через $('label[for=" + this.id + '"]')
.
Как по мне, если вы работаете с несколькими дочерними узлами внутри родительского, то можно использовать всплытие событий. И не использовать 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/
Спасибо, что напомнили — обязательно перепишу это безобразие с гордой пометкой «tutorial», как появится время.
Нет отображения фокуса.
…
Не работает драг-энд-дроп.
Поле для drag&drop нужно делать, а не на кнопку кидать. Кидать на кнопку — это уже маразм какой-то…
Нет поддержки доступности (речевые технологии, тач-устройства, пульт телевизора).
Речевые?.. Вообще никак не знаком с этим. Как обычный input file с помощью речевых открыть?
Тач? Он не будет работать? Пальцем не попадёшь или что?
Телевизор? Меня интересует сейчас не поддержка телевизоров, а хранилище, с которого будут загружаться файлы. Тебе, как минимум, нужна флешка. Ситуация, наверно, будет такая: Ты идёшь к компу и скидываешь на флешку файлы, достаёшь из компа флешку и идёшь к телевизору, вставляешь её (а usb вход находится сзади, и тебе нужно еще попотеть, чтобы эту флешку вставить) в телевизор, и начинаешь тыкать пультом по форме… Товарищ, я смотрю вы знаете толк в извращениях. Хотя, я наверно не прав. Я подумаю на счёт этого…
Не отображается имя загруженного файла.
Как будто надо. Ты еще попроси превью изображения с функцией перетаскивания… Наша цель: быстро и просто.
Нет отображения ошибок (неверный формат файла, слишком большой размер).
Ну это не моя забота. Для проверки формы пишется отдельная функция, которая меня не касается, и разработчик её расширяет так, как ему вздумается. К примеру, у меня валидацию устраивает yii, и все у меня ошибки нормально отображаются.
Захардкоженные строки текста. Будут трудности с переводом.
На другой язык? Трудности… Трудности будут также для людей с ограниченными возможностями, для детей и для стариков. О каком переводе идёт речь? Для разных языков нужно писать разные сайты с нуля, придерживаясь законам основного дизайна. Писать один и тот же код для нескольких языков тоже самое, что делать резиновые сайты.
Негибкая вёрстка.
Грубые ошибки вёрстки (захардкоженный размер кнопки, не указано семейство шрифтов, не указан цвет фона,
Размер кнопки надо было в процентах указывать?
Слово Tahoma просто так написано? Для красоты?
Цвет фона указан. Он прозрачный.
Вот блин, цвет не контрастный. Чтож теперь делать? Этож обязательное правильно: использовать зелёный цвет. Иначе же форма работать не будет.
transition: all и? Что не так?
Лишняя зависимость от jQuery, когда в ней нет никакой острой необходимости.
Наличие формы, как бы уже подразумевает наличие jquery. Писать на голом javascript тоже самое, что купить машину и ходить пешком.
Не работает при выключенном (сломанном) яваскрипте.
Если яваскрипт у юзверя сломан, то он до моего input file даже не дойдёт. так что тут мне не о чем переживать.
А какие проблемы вы решали?
Внешний вид. На разных браузерах input кроме того, что страшный, так еще и везде разный. Хотелось бы придерживаться основному стилю/дизайну при разработке.
К примеру, у меня валидацию устраивает yii, и все у меня ошибки нормально отображаются.Я знал! Я знал!
это уже маразм какой-тоМаразм — это то, что вы решили, что убирать стандартное поведение — это хорошая идея.
Как будто надо.Ну это вообще пушка. Хорошо, таких как вы меньшинство, по крайней мере на крупных ресурсах.
Писать один и тот же код для нескольких языков тоже самое, что делать резиновые сайты.Это даже комментировать не хочется.
Сколько вам лет?
О каком переводе идёт речь? Для разных языков нужно писать разные сайты с нуля, придерживаясь законам основного дизайна. Писать один и тот же код для нескольких языков тоже самое, что делать резиновые сайты.
Неадекватно.
> Захардкоженные строки текста. Будут трудности с переводом.
На другой язык? Трудности… Трудности будут также для людей с ограниченными возможностями, для детей и для стариков.
Указанные вами трудности связаны с физическими возможностями и знаниями пользователей. А вам говорят про трудности при разработке и поддержке.
Для разных языков нужно писать разные сайты с нуля, придерживаясь законам основного дизайна.
Вы в курсе, что копи-паста это плохой подход к проектированию? Как потом это все поддерживать? Да и зачем тратить столько времени и сил, когда есть способы гораздо проще.
Размер кнопки надо было в процентах указывать?
Не надо было его вообще указывать. Чтобы другому программисту не пришлось переопределять его в 10 местах, если понадобилось размер шрифта увеличить или текст подлиннее написать.
На немецком, например, эта надпись в 1.5 раза длиннее. Как вы предлагаете придерживаться законов основного дизайна? Руками размер каждой кнопки задавать, чтобы внутренние отступы нормально выглядели? Или проще все-таки отступы стандартными средствами задать?
Наличие формы, как бы уже подразумевает наличие jquery.
Ничего подобного. Это конкретно в Yii работа с полями формы происходит через jQuery.
А теперь поговорим про скорость, мой всё еще не менее дорогой друг.
Что быстрее .prev() или label[for="(this).attr('id')"]? Ну вот серьёзно, представь, что проще сделать?
Давай я для тебя аналогию проведу, а то, мне кажется, ты сразу не поймёшь мою мысль.
Вот смотри: допустим ты живёшь на 50-ом этаже многоэтажного дома. В квартире, к примеру, 297. И вот тебе по срочной необходимости понадобилась соль. Да, банальная такая соль. Ты знаешь, что соль может дать тебе твой сосед Вася, который живёт в соседней квартире на площадке твоего этажа, но номер квартиры забыл и посчитать не можешь. Но так как ты у нас очень педантичный человек, тебе обязательно нужно знать номер квартиры. И что делаешь ты? Ты выходишь из своей квартиры, спускаешься на первый этаж и начинаешь заходить во все квартиры, проверяя, живёт ли в этой квартире Вася. «Вася тут?» — обращаешься ты к жильцу квартиры номер 1. И так далее. Каждую, мать её, квартиру проверяешь. И потом уже, под вечер, когда ты дошел до 298 квартиры, где живёт наш Вася, ты просишь у него соль. Красаучик, ничего не сказать.
Вот и label[for="(this).attr('id')"] тоже самое. Начинаешь перебирать весь документ, в надежде найти label, у которого id равен id input. Ключевое слово, если ты не понял, здесь «весь документ».
С чего вы взяли, что поиск по селектору осуществляется перебором?
Что будет, если между инпутом и лэйблом добавится элемент?
Можете переписать это на DOM API? Вы удивитесь, насколько бесполезен тут jquery.
А с чего вы взяли что это не перебор файла? Компьютер сразу знает, где у него находится 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
Веб-видео (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.
Позвольте присоедениться к срачу! :)А давайте!
Ну как же, проблема же не в кодеках, железе, прожорливой технологии, оптимизации или в чем-то там еще. Проблема в том, что мы с вами тут только и делаем, что говнокодим и, вообще, ломаем веб, негодяи. Все же просто.
Но здесь… Здесь что-то новенькое.
Это для вас новенькое. Переменные вводятся для понятности и упрощения поддержки.
А теперь поговорим про скорость
А вот поговорим. Что быстрее, обращение к элементу напрямую средствами браузера или через дополнительную библиотеку, которая обращается к нему средствами браузера? Ну вот серьёзно, представьте, что проще сделать? Давайте я для вас аналогию проведу, а то, мне кажется, вы сразу не поймёте мою мысль.
Допустим, вам по срочной необходимости понадобилась соль. Да, банальная такая соль. Вы знаете, что соль может дать ваш сосед Вася, который живёт в соседней квартире на площадке вашего этажа. Но вы не хотите просто зайти к нему и попросить. Вы звоните своему юристу, просите его «найди Васю и спроси у него соль», он ищет адрес Васи в городской базе данных, приезжает к нему, составляет договор, берет соль, заворачивает ее в пакет, передает вам, вы разворачиваете пакет и берете соль. Зато вы точно знаете, что юрист решит все вопросы сам — и присутствие/отсутствие Васи и наличие у него соли.
К чему это я? К тому, что если вы используете 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>
Результаты примерно такие:
testJQuery() time: 343 ms.
testNative() time: 93 ms.
Разница, как видите, почти в 4 раза. А потом мы виним хром, который много памяти жрёт. Всё лагает, зависает и требует ОЗУ. Из-за такого кода, как у вас, между прочим.
Намного ж изящнее и проще использовать this.id и this.files
библиотека отличная конечно, но порой ее суют куда не попадя — какое-то #жиквериголовногомозга прям
$(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 = 'Выберите файлы';
});
Мне пару часов назад хабр показывал рекламу «Стань программистом за 2 часа», видимо примерно этого уровня оттуда выходят.
Array.apply(null, document.querySelectorAll('input[type=file].my')).forEach(input => {
input.addEventListener('change', e => {
let label = Array.apply(null, document.querySelectorAll('label')).find(l => l.htmlFor === input.id);
label.innerHTML = (input.value ? 'Выбрано файлов: ' + input.files.length : 'Выберите файлы')
});
})
Пишем самый простой и быстрый input type file