Использование 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 с помощью сценариев на стороне сервера может привести к довольно невероятным вещам.

Не в каком-либо общепринятом смысле слова "внутри 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 файл.

Удачи.

Другие вопросы по тегам