Русские документы
Ежедневные компьютерные новости RSS rusdoc.ru  Найти :
Новости
Последние поступления
Книжный магазин
  Hardware:
Видеоустройства
Системные платы
Процессоры
Мобильные устройства
Аудиосистема
Охлаждение системы
Накопители информации
КПК и ноутбуки
Телефоны и связь
Периферия
Система
Сети
Разные устройства
 
  Programming:
Web-разработка
Языки программирования
Технологии и теория
Разработка игр
Программная инженерия
 
  Software:
Операционные системы
Windows 7
Базы данных
Обзоры программ
Графика и дизайн
   
  Life:
Компьютерная жизнь
Разные материалы
   
Партнеры
Публикация
Правовая информация
Реклама на сайте
Обратная связь
Экспорт в RSS Экспорт в RSS2.0
    Читать в Яндекс.Ленте



Стилизация файл-инпутов

Раздел: Programming / Вебмастеру @ 04.08.2008 | Ключевые слова: input внешний вид инпута стилизация файл-инпут версия для печати

Автор: Zhendalf
Источник: временно.нет

Результат стилизации файл-инпута
Привет. Сегодня я хочу вам рассказать о том, как можно изменить внешний вид файлового инпута.


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


Для начала давайте посмотрим на то, как отображаются файл-инпуты без применения каких-либо стилей в разных браузерах.


пустые инпуты


Как видим, во всех браузерах кроме сафари имеется текстовое поле, а справа от него кнопка. Расскажу о различиях. В Опере и IE мы можем написать адрес файла вручную (сомневаюсь, что кто-либо когда-либо пользовался этой возможностью). Файерфокс, несмотря на то, что у него есть текстовое поле, не дает нам вписать туда адрес файла. Вместо этого появляется окно выбора файла как при нажатии на кнопку «Обзор».

Давайте теперь выберем в этих полях какой-либо файл.

заполненные инпуты


В результате везде, кроме сафари, мы видим начало адреса, которое не несет почти никакой смысловой нагрузки. Я сомневаюсь, что кто-то об этом не знал, но на эту глупость обратили внимание только ребята из эпла и сделали возможность сразу увидеть не только название выбранного файла, но и иконку. Такую же функциональность файл-инпута мы и собираемся реализовать для всех браузеров.


Но cначала ознакомимся с проблематикой.

1. Средствами JS мы не можем сымитировать клик на такой инпут. Вот что говорится об этом в святом писании спецификации DOM:

click

Simulate a mouse-click. For INPUT elements whose type attribute has one of the following values: “button”, “checkbox”, “radio”, “reset”, or “submit”.

No Parameters
No Return Value
No Exceptions


То есть методом 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(http://www.rusdoc.ru/articles/17537/images/button.jpg) no-repeat left top;
float: left;
}

.blocker {
position: absolute;
z-index: 3;
width: 150px;
height: 21px;
background: url(http://www.rusdoc.ru/articles/17537/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(http://www.rusdoc.ru/articles/17537/images/button_active.jpg) no-repeat left top;
display: none;
}
style>

Результат выглядит приблизительно так:
приблизительный результат

Обведенное красным — blocker, файл-инпут показан с половинной прозрачностью.

Теперь при выборе файла (событие onchange) мы должны вырезать название файла из value нашего файл-инпута, определить тип файла по расширению и сместить фон, чтобы показывалась нужная иконка. Обратите внимание, что в разных операционных системах путь к файлу может быть через прямой слэш (в Mac OS, например), или через обратный (Виндуз), поэтому чтобы вырезание названия файла работало везде необходимо два регулярных выражения.

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(http://www.rusdoc.ru/articles/17537/images/icons.png) no-repeat 0 -`+pos+`px`;
};

};
function MakeActive() {
activeButton.style.display = `block`;
};
function UnMakeActive() {
activeButton.style.display = `none`;
};



Последние две функции MakeActive и UnMakeActive добавляют hover эффект к нашей кнопочке. Активное и неактивное состояние кнопки разбито в два файла, чтобы легко можно было реализовать анимацию для появления кнопки.


Отлично, но осталось несколько проблем. Первая: в разметке большое количество дивов, которые портят семантику.

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


На странице у нас останется только два элемента:

<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(http://www.rusdoc.ru/articles/17537/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);
};

Теперь посмотрим как это выглядит.

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

Если пожелают читатели, то в добавок к скрипту мы сделаем специализированный контрол для asp.net-программеров, позволяющий легко добавлять такие стилизованные инпуты на страницу.

Архив со скриптами урока


Оригинал статьи на временно.нет



* Source code was highlighted with Source Code Highlighter

Это интересно:








версия для печатиРаспечатать статью


Вернуться в раздел: Programming / Вебмастеру


Реклама:
Читать наc на:

Add to Google
Читать в Яндекс.Ленте






Rambler's Top100
© Copyright 1998-2012 Александр Томов. All rights reserved.