Использование Javascript в CSS
Можно ли использовать Javascript внутри CSS?
Если да, можете ли вы привести простой пример?
7 ответов
IE и Firefox содержат способы выполнения JavaScript из CSS. Как отмечает Паоло, одним из способов в IE является expression
техника, но есть и более неясное поведение HTC, при котором отдельный XML, содержащий ваш скрипт, загружается через CSS. Подобная техника для Firefox существует с использованием XBL. Эти методы не извлекают JavaScript из CSS напрямую, но эффект тот же.
HTC с IE
Используйте правило CSS примерно так:
body {
behavior:url(script.htc);
}
и в этом файле script.htc есть что-то вроде:
<PUBLIC:COMPONENT TAGNAME="xss">
<PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="main()" LITERALCONTENT="false"/>
</PUBLIC:COMPONENT>
<SCRIPT>
function main()
{
alert("HTC script executed.");
}
</SCRIPT>
Файл HTC выполняет main()
функция на мероприятии ondocumentready
(ссылаясь на готовность документа HTC.)
XBL с Firefox
Firefox поддерживает аналогичный хак, выполняющий XML-сценарии, используя XBL.
Используйте правило CSS примерно так:
body {
-moz-binding: url(script.xml#mycode);
}
и внутри вашего script.xml:
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtml">
<binding id="mycode">
<implementation>
<constructor>
alert("XBL script executed.");
</constructor>
</implementation>
</binding>
</bindings>
Весь код внутри тега конструктора будет выполнен (хорошая идея - обернуть код в раздел CDATA.)
В обоих методах код не выполняется, если селектор CSS не соответствует элементу в документе. Используя что-то вроде body
, он будет выполняться сразу при загрузке страницы.
Я думаю, что вы можете думать о том, expressions
или "динамические свойства", которые поддерживаются только IE и позволяют установить свойство для результата выражения javascript. Пример:
width:expression(document.body.clientWidth > 800? "800px": "auto" );
Этот код заставляет IE эмулировать max-width
свойство это не поддерживает.
Однако, учитывая все обстоятельства, избегайте их использования. Они плохие, плохие.
Чтобы облегчить потенциальное решение вашей проблемы, учитывая предоставленную вами информацию, я предполагаю, что вы ищете динамический CSS. Если это так, вы можете использовать для этого язык сценариев на стороне сервера. Например (и я очень люблю делать такие вещи):
styles.css.php:
body
{
margin: 0px;
font-family: Verdana;
background-color: #cccccc;
background-image: url('<?php
echo 'images/flag_bg/' . $user_country . '.png';
?>');
}
Это установит фоновое изображение на то, что было сохранено в переменной $user_country. Это только один пример динамического CSS; Есть практически безграничные возможности при комбинировании CSS и кода на стороне сервера. В другом случае можно сделать что-то вроде предоставления пользователю возможности создать собственную тему, сохранить ее в базе данных, а затем использовать PHP для установки различных свойств, например:
user_theme.css.php:
body
{
background-color: <?php echo $user_theme['BG_COLOR']; ?>;
color: <?php echo $user_theme['COLOR']; ?>;
font-family: <?php echo $user_theme['FONT']; ?>;
}
#panel
{
font-size: <?php echo $user_theme['FONT_SIZE']; ?>;
background-image: <?php echo $user_theme['PANEL_BG']; ?>;
}
Еще раз, тем не менее, это всего лишь пример "из головы в голову"; Использование возможностей динамического CSS с помощью сценариев на стороне сервера может привести к довольно невероятным вещам.
IE поддерживает CSS- выражения:
width:expression(document.body.clientWidth > 955 ? "955px": "100%" );
но они не являются стандартными и не переносимы во всех браузерах. Избегайте их, если это возможно. Они устарели с IE8.
Для более актуального решения, используя Vue.
var vue = new Vue({
el : "#app",
data: {
styleObject: {
color: 'red',
fontSize: '20px'
},
activeColor: 'blue',
activeColor2: 'green',
fontSize: '30px'
},
methods : {
color: function (color) {
this.activeColor2 = color;
}
},
mounted: function () {
if(1 > 0) {
this.color('gray');
}
}
})
<script src="https://unpkg.com/vue@2.5.2/dist/vue.js"></script>
<ul id="app" :style="styleObject">
<li>test</li>
<li :style="{color: activeColor2, fontSize: fontSize}">test</li>
<li>test</li>
<li>test</li>
<li :style="{color: activeColor, fontSize: fontSize}">test</li>
<li>test</li>
<li>test</li>
</ul>
Я столкнулся с подобной проблемой и разработал два автономных инструмента для достижения этой цели:
CjsSS.js - это инструмент Vanilla Javascript (так что никаких внешних зависимостей), который поддерживает возврат к IE6.
ngCss - это Angular Module+Filter+Factory (он же плагин), который поддерживает Angular 1.2+ (так что вернемся к IE8)
Оба эти набора инструментов позволяют вам делать это в теге STYLE или во внешнем файле *.css:
/*<script src='some.js'></script>
<script>
var mainColor = "#cccccc";
</script>*/
BODY {
color: /*{{mainColor}}*/;
}
И это на вашей странице style
атрибуты:
<div style="color: {{mainColor}}" cjsss="#sourceCSS">blah</div>
или же
<div style="color: {{mainColor}}" ng-css="sourceCSS">blah</div>
ПРИМЕЧАНИЕ: в ngCss вы также можете сделать $scope.mainColor
на месте var mainColor
По умолчанию Javascript выполняется в изолированном IFRAME, но поскольку вы создаете свой собственный CSS и размещаете его на своем собственном сервере (так же, как ваши файлы *.js), то XSS не является проблемой. Но песочница обеспечивает гораздо большую безопасность и спокойствие.
CjsSS.js и ngCss находятся где-то между другими инструментами для выполнения аналогичных задач:
LESS, SASS и Stylus являются только препроцессорами и требуют от вас изучения нового языка и манипулирования вашим CSS. В основном они расширили CSS новыми языковыми возможностями. Все они также ограничены плагинами, разработанными для каждой платформы, в то время как CjsSS.js и ngCss позволяют вам включать любую библиотеку Javascript через
<script src='blah.js'></script>
прямо в вашем CSS!AbsurdJS увидел те же проблемы и пошел прямо противоположное направление препроцессоров выше; вместо расширения CSS, AbsurdJS создал библиотеку Javascript для генерации CSS.
CjsSS.js и ngCss заняли второе место; вы уже знаете CSS, вы уже знаете Javascript, так что просто позвольте им работать вместе простым и интуитивно понятным способом.
Это оказывается очень интересным вопросом. Если установлено более ста свойств, можно подумать, что вам будет разрешено набирать.clickable { onclick: "alert('hi!');"; } в вашем CSS, и это будет работать. Это интуитивно понятно, в этом много смысла. Это было бы поразительно полезно в динамически генерируемых массивах пользовательского интерфейса.
Эта проблема:
Полиция CSS в своей бесконечной мудрости нарисовала китайскую стену между представлением и поведением. Любой HTML-код, помеченный должным образом, намеренно не поддерживается CSS. ( Полная таблица свойств)
Лучший способ обойти это - использовать jQuery, который настраивает интерпретируемый движок в фоновом режиме для выполнения того, что вы пытались сделать с CSS в любом случае. Смотрите эту страницу: Добавить Javascript Onclick в.css файл.
Удачи.