|
Сегодня я хочу вам рассказать о том, как можно изменить внешний вид файлового инпута, как стилизовать файл-инпут под свой дизайн, как стилизовать <input type="file">. Хватит ключевых слов =). Суть я думаю вы поняли. Дело в том, что изменение внешнего вида инпутов, как правило, не вызывает трудностей, но этот вид инпутов отличается от остальных. В первую очередь это связано с безопасностью, во вторую с тем, что каждый браузер по своему отображает этот элемент, и на это почти нельзя повлиять. Как добиться того внешнего вида файл-инпута, который вам нужен и расскажет эта статья. Для начала давайте посмотрим на то, как отображаются файл-инпуты без применения каких-либо стилей в разных браузерах.
Как видим, во всех браузерах кроме сафари имеется текстовое поле, а справа от него кнопка. Расскажу о различиях. В Опере и IE мы можем написать адрес файла вручную (сомневаюсь, что кто-либо когда-либо пользовался этой возможностью). Файерфокс, несмотря на то, что у него есть текстовое поле, не дает нам вписать туда адрес файла. Вместо этого появляется окно выбора файла как при нажатии на кнопку «Обзор».
В результате везде, кроме сафари мы видим начало адреса, которое не несет почти никакой смысловой нагрузки. Я сомневаюсь, что кто-то об этом не знал, но на эту глупость обратили внимание только ребята из эпла и сделали возможность сразу увидеть не только название выбранного файла, но и иконку. Такую же функциональность файл-инпута мы и собираемся реализовать для всех браузеров. Но cначала ознакомимся с проблематикой. click То есть методом click мы можем сымитировать клик почти на всех типах инпутов, но не на файл-инпуте. Это сделано чтобы обезопасить компьютер клиента: в противном случае хозяин сайта мог бы без проблем получать любые файлы с компьютера клиента. Хотя с другой стороны, по клику вызывается только окно выбора файла. Так или иначе, в девелопер-центре файерфокса этот факт обозначен как баг. Решение есть, и мы не придумывали велосипед, мы его тюнинговали. Все, кто стилизует инпуты действуют по той же схеме: создается инпут с нулевой прозрачностью и ставится поверх кнопки или изображения, которые представляют собой кнопку выбора файла. Основная трудность в следующей проблеме. 2. Мы не можем свободно влиять на размеры кнопок «обзор», чтобы подогнать инпут под размер перекрываемой картинки. В файерфоксе мы вообще не можем изменить внешний вид файл-инпута средствами css (кроме высоты). То есть задача заключается определении оптимального размера перекрываемой картинки, чтобы минимальное количество пикселей было некликабельно, а пустые области не реагировали на клик. Посмотрим на кликабельные области и их размеры в разных браузерах.
Все что внутри голубой обводки - кликабельная область. Замечу, что высоту кнопок мы можем увеличить, а вот ширину — нет. Проблемы ясны. Переходим к делу. Для начала нарисуем кнопку для выбора файла. Вот какая получилась у меня. В обычном состоянии:
при наведении:
Теперь для разных типов файлов подготовим иконки и объединим их в один файл.
Итак, сверстаем шаблон инпута: HTML:<div class="blocker" <!--блок, перекрывающий поле ввода слева от кнопки--> <input type="file" id="File1" class="customFile" /> <div id="BrowseButton" title="Выбрать файл" class="fakeButton" <div id="FileName" <!--сюда мы будем вставлять имя файла и иконку-->
CSS:<style type="text/css" #File1 { position: absolute; } .customFile { width: 219px; margin-left: -140px; cursor: default; height: 21px; z-index: 2; filter: alpha(opacity: 0); opacity: 0; } .fakeButton { position: absolute; z-index: 1; width: 85px; height: 21px; background: url(images/button.jpg) no-repeat left top; float: left; } .blocker { position: absolute; z-index: 3; width: 150px; height: 21px; background: url(images/transparent.gif); margin-left: -155px; } #FileName { position: absolute; height: 15px; margin-left: 90px; font-family: Verdana; font-size: 8pt; color: Gray; margin-top: 2px; padding-top: 1px; padding-left: 19px; } #activeBrowseButton { background: url(images/button_active.jpg) no-repeat left top; display: none; } </style
Результат выглядит приблизительно так:
Обведенное красным — blocker, файл-инпут показан с половинной прозрачностью.
function HandleChanges() { file = fileInput.value; reWin = /.*(.*)/; var fileTitle = file.replace(reWin, "$1"); //выдираем название файла для windows reUnix = /.*/(.*)/; fileTitle = fileTitle.replace(reUnix, "$1"); //выдираем название файла для unix-систем fileName.innerHTML = fileTitle; var RegExExt =/.*.(.*)/; var ext = fileTitle.replace(RegExExt, "$1");//и его расширение var pos; if (ext) { switch (ext.toLowerCase()) { case 'doc': pos = '0'; break; case 'bmp': pos = '16'; break; case 'jpg': pos = '32'; break; case 'jpeg': pos = '32'; break; case 'png': pos = '48'; break; case 'gif': pos = '64'; break; case 'psd': pos = '80'; break; case 'mp3': pos = '96'; break; case 'wav': pos = '96'; break; case 'ogg': pos = '96'; break; case 'avi': pos = '112'; break; case 'wmv': pos = '112'; break; case 'flv': pos = '112'; break; case 'pdf': pos = '128'; break; case 'exe': pos = '144'; break; case 'txt': pos = '160'; break; default: pos = '176'; break; }; fileName.style.display = 'block'; fileName.style.background = 'url(images/icons.png) no-repeat 0 -'+pos+'px'; }; }; function MakeActive() { activeButton.style.display = 'block'; }; function UnMakeActive() { activeButton.style.display = 'none'; };
Последние две функции MakeActive и UnMakeActive добавляют hover эффект к нашей кнопочке. На странице у нас останется только два элемента: <div id="wrapper" <input id="File1" type="file"/> </div
Если у пользователя будет отключен JavaScript, он увидит обычный файл-инпут. В противном случае произойдет следующее: window.onload = WindowOnLoad; var fileInput = document.getElementById('File1'); var fileName = document.createElement('div'); fileName.style.display = 'none'; fileName.style.background = 'url(images/icons.png)'; var activeButton = document.createElement('div'); var bb = document.createElement('div'); var bl = document.createElement('div'); function WindowOnLoad() { var wrap = document.getElementById('wrapper'); fileName.setAttribute('id','FileName'); activeButton.setAttribute('id','activeBrowseButton'); fileInput.value = ''; fileInput.onchange = HandleChanges; fileInput.onmouseover = MakeActive; fileInput.onmouseout = UnMakeActive; fileInput.className = 'customFile'; bl.className = 'blocker'; bb.className = 'fakeButton'; activeButton.className = 'fakeButton'; wrap.appendChild(bb); wrap.appendChild(bl); wrap.appendChild(activeButton); wrap.appendChild(fileName); };Теперь посмотрим как это выглядит. Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
|