Разве не забавно, что мы играем с новейшими техниками CSS, такими как тени и переходы? Есть только одна проблема: как мы компенсируем или, что более важно, обнаруживаем браузеры, которые их не поддерживают? Ну, есть несколько решений. В этом уроке и скринкасте мы создадим функцию JavaScript, которая будет принимать имя свойства CSS в качестве параметра и будет возвращать boolean , указывающее, поддерживает ли браузер переданное свойство.
Предпочитаете видеоурок?
Шаг 1
Давайте начнем с определения того, как мы хотим вызвать нашу function . Здесь все будет просто; что-то вроде следующего должно сделать свое дело:
|
1
2
3
|
if ( supports(‘textShadow’) ) {
document.documentElement.className += ‘ textShadow’;
}
|
Это должен быть последний вызов function . Когда мы передаем имя свойства CSS в функцию supports() , оно возвращает boolean . Если true , мы прикрепим className к documentElement или <html> . Затем мы получим новое имя `class` для подключения из нашей таблицы стилей.
Шаг 2
Далее мы создадим supports() function .
|
1
2
3
|
var supports = (function() {
})();
|
Почему мы не делаем supports равной стандартной функции? Ответ в том, что сначала нам нужно немного подготовиться , и нет абсолютно никакой причины повторять эти задачи снова и снова при каждом вызове функции. В подобных случаях лучше сделать supports равной тому, что возвращается из самовыполняющейся функции.
Шаг 3
Чтобы проверить, поддерживает ли браузер определенные свойства, нам нужно создать элемент * dummy * для тестирования. Этот сгенерированный элемент никогда не будет вставлен в DOM; думать об этом как о манекене!
|
1
|
var div = document.createElement(‘div’);
|
Как вы, вероятно, знаете, есть несколько префиксов поставщиков, которые мы можем использовать при работе со свойствами CSS3:
- -moz
- -webkit
- -о
- -Миз
- -khtml
Наш JavaScript должен будет отфильтровать эти префиксы и протестировать их. Итак, давайте разместим их в array ; мы назовем это, vendors .
|
1
2
|
var div = document.createElement(‘div’),
vendors = ‘Khtml Ms O Moz Webkit’.split(‘ ‘);
|
Использование функции
split()для созданияarrayизstringпо общему признанию, лениво, но экономит несколько секунд!
Поскольку мы будем фильтровать этот array , давайте будем хорошими парнями и девочками, а также кешируем length array .
|
1
2
3
|
var div = document.createElement(‘div’),
vendors = ‘Khtml Ms O Moz Webkit’.split(‘ ‘),
len = vendors.length;
|
Подготовительная работа, приведенная выше, является статической по своей природе, и ее не нужно повторять каждый раз, когда мы вызываем supports() . Вот почему мы запускаем его только один раз, когда страница загружается. Теперь давайте return function которая будет фактически назначена variable .
|
1
2
3
|
return function(prop) {
};
|
Прелесть
closuresв том, что, хотяsupports()равна возвращаемойfunction, она все еще имеет доступ к переменнымdiv,vendorsиlen.
Шаг 4
Непосредственный тест: если переданное свойство доступно атрибуту style div , мы знаем, что браузер поддерживает это свойство; так return true .
|
1
2
3
|
return function(prop) {
if ( prop in div.style ) return true;
};
|
Представьте, скажем, свойство CSS3 text-shadow . Большинство современных браузеров поддерживают его без необходимости использования префикса поставщика. Имея это в виду, зачем фильтровать все префиксы, если нам это не нужно? Вот почему мы размещаем этот чек сверху.
Шаг 5
Скорее всего, вы привыкли вводить имена свойств CSS3, например: -moz-box-shadow . Однако, если в Firebug вы MozBoxShadow object style , вы обнаружите, что он записан как MozBoxShadow . Таким образом, если мы проверим:
|
1
|
‘mozboxShadow’ in div.style // false
|
False будет возвращена. Это значение чувствительно к регистру.

Это означает, что, если пользователь передаст boxShadow функции boxShadow supports() , boxShadow сбой. Давайте подумаем и проверим, является ли первая буква аргумента строчной. Если это так, мы исправим ошибку для них.
|
1
2
3
4
5
6
7
8
|
return function(prop) {
if ( prop in div.style ) return true;
prop = prop.replace(/^[az]/, function(val) {
return val.toUpperCase();
});
};
|
Регулярные выражения на помощь! Выше мы проверяем, есть ли одна строчная буква в начале строки ( ^ ). Только при условии, что он найден, мы используем функцию toUpperCase() чтобы заглавные буквы.
Шаг 6
Затем нам нужно отфильтровать массив vendors и проверить, есть ли совпадение. Например, если передано box-shadow , мы должны проверить, содержит ли атрибут style div любое из следующего:
- MozBoxShadow
- WebkitBoxShadow
- MsBoxShadow
- OBoxShadow
- KhtmlBoxShadow
Если совпадение найдено, мы можем return true , потому что браузер действительно предоставляет поддержку для теней блоков!
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
return function(prop) {
if ( prop in div.style ) return true;
prop = prop.replace(/^[az]/, function(val) {
return val.toUpperCase();
});
while(len—) {
if ( vendors[len] + prop in div.style ) {
return true;
}
}
};
|
Хотя мы могли бы использовать оператор for для фильтрации array , в этом нет особой необходимости.
- Порядок не важен
-
whileоператоры быстрее набираются и требуют меньше символов - Есть небольшое улучшение производительности
Не смущайтесь vendors[len] + prop ; просто замените эти имена их реальными значениями: MozBoxShadow .
Шаг 7
Но что, если ни одно из этих значений не совпадает? В этом случае браузер не поддерживает свойство, и в этом случае мы должны return false .
|
1
2
3
4
5
6
|
while(len—) {
if ( vendors[len] + prop in div.style ) {
return true;
}
}
return false;
|
Это должно сделать это для нашей функции! Давайте проверим это, применив className к элементу html , если браузер поддерживает, скажем, свойство text-stroke (что делает только webkit).
|
1
2
3
|
if ( supports(‘textStroke’) ) {
document.documentElement.className += ‘ textStroke’;
}
|
Шаг 8: Использование
С именем class которое мы теперь можем подключить , давайте попробуем это в нашей таблице стилей.
|
01
02
03
04
05
06
07
08
09
10
|
/* fallback */
h1 {
color: black;
}
/* text-stroke support */
.textStroke h1 {
color: white;
-webkit-text-stroke: 2px black;
}
|
Окончательный исходный код
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
var supports = (function() {
var div = document.createElement(‘div’),
vendors = ‘Khtml Ms O Moz Webkit’.split(‘ ‘),
len = vendors.length;
return function(prop) {
if ( prop in div.style ) return true;
prop = prop.replace(/^[az]/, function(val) {
return val.toUpperCase();
});
while(len—) {
if ( vendors[len] + prop in div.style ) {
// browser supports box-shadow.
// Or use a bang (!) to test if the browser doesn’t.
return true;
}
}
return false;
};
})();
if ( supports(‘textShadow’) ) {
document.documentElement.className += ‘ textShadow’;
}
|
Для более полного решения обратитесь к библиотеке Modernizr .