Создайте правило / класс CSS с помощью jQuery во время выполнения

189

Обычно у меня есть файл CSS, который имеет следующее правило:

#my-window {
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}

Как я могу избежать создания такого статического файла CSS, добавляя информацию CSS во время выполнения действий к телу, или что-то подобное? (только с использованием jQuery)

Я хочу определить его один раз, но с помощью jQuery и использовать его много раз позже; вот почему я не хочу добавлять его каждый раз к конкретным элементам DOM.

Я знаю простые функции ( css("attr1", "value");), но как мне создать полное правило CSS для повторного использования?

Stephan
источник

Ответы:

269

Вы можете создать элемент стиля и вставить его в DOM

$("<style type='text/css'> .redbold{ color:#f00; font-weight:bold;} </style>").appendTo("head");
$("<div/>").addClass("redbold").text("SOME NEW TEXT").appendTo("body");

протестировано на Opera10 FF3.5 iE8 iE6

Тарас Бульба
источник
Суть самодостаточна. Вы можете создать его локально, и он будет работать просто отлично. Прямая ссылка на ссылку для скачивания: gist.github.com/gists/714352/download
Даниэль Рибейро
Нет проблем. Иногда это может быть ошибка младшей версии jQuery или просто неправильная настройка. Дело в том, что js-приложения заключаются в следующем: если они не работают, они просто не работают вообще. Нет прощения.
Даниэль Рибейро
1
Выдает ошибку « Неожиданный вызов доступа к методу или свойству » для меня в IE8. Я должен был следовать этой статье, чтобы заставить ее работать.
Брэндон Бун
6
Там может быть только 31 стили в странице в IE9- blogs.msdn.com/b/ieinternals/archive/2011/05/14/...
IvanH
1
Если это не работает Попробуйте добавить стиль к body. то есть$("<style>...</style>").appendTo("body");
inDream
118

Просто

$("<style>")
    .prop("type", "text/css")
    .html("\
    #my-window {\
        position: fixed;\
        z-index: 102;\
        display:none;\
        top:50%;\
        left:50%;\
    }")
    .appendTo("head");

Заметили обратную косую черту? Они используются для объединения строк в новых строках. Оставляя их, выдает ошибку.

богонько
источник
6
Это. Должен быть принятый ответ. Это на самом деле отвечает на вопрос.
Йоханнес Пилле
2
Я согласен с @JohannesPille, это реальный ответ!
баю
не работает в Cordova IOS. не могли бы вы предложить по этому поводу?
RamGrg
2
Довольно эффективный и простой. Как только новое правило введено в заголовок, вы можете получить его в любом месте вашей страницы, включая PHP.
Брайс Кустильяс
такой же , как stackoverflow.com/questions/1720320/...
user1742529
17

Вы можете применить CSS объект. Таким образом, вы можете определить свой объект в вашем javascript следующим образом:

var my_css_class = { backgroundColor : 'blue', color : '#fff' };

А затем просто примените его ко всем элементам, которые вы хотите

$("#myelement").css(my_css_class);

Так что это многоразово. С какой целью вы бы это сделали?

Юваль Карми
источник
22
Я бы сказал, что это правило CSS, а не класс CSS.
Hippietrail
17
Этот ответ вводит в заблуждение. Аскер хотел создать правило CSS во время выполнения, а не устанавливать стиль определенного элемента на постоянное (повторно используемое) объявление CSS.
Дан Даскалеску
4
Это не совсем то, что они просили, но это правильное решение :) Заполнение домена дополнительными элементами <style> имеет неприятный запах кода
Кевин
3
Как вы удалите эти правила, применяемые в случае необходимости, это возможно с другими решениями ...
Вишванат
@Kevin - это может быть так, но бывают случаи, когда это именно то, что вам нужно. например - когда элемент создается заново с помощью некоторого ajax-скрипта, и вам нужно сохранить новое правило стиля.
Биллиноа
12

Вы можете использовать insertRule, если вам не нужно поддерживать IE <9, в соответствии с dottoro . Там также есть немного кросс-браузерного кода.

document.styleSheets[0].insertRule('#my-window {\
    position: fixed;\
    z-index: 102;\
    display:none;\
    top:50%;\
    left:50%;\
}', 0)
Шон
источник
9

Вот плагин jquery, который позволяет вам внедрять CSS:

https://github.com/kajic/jquery-injectCSS

Пример:

$.injectCSS({
    "#my-window": {
        "position": "fixed",
        "z-index": 102,
        "display": "none",
        "top": "50%",
        "left": "50%"
    }
});
Роберт Кайич
источник
9

В этом нет ничего нового по сравнению с некоторыми другими ответами, поскольку в нем используется концепция, описанная здесь и здесь , но я хотел использовать объявление в стиле JSON:

function addCssRule(rule, css) {
  css = JSON.stringify(css).replace(/"/g, "").replace(/,/g, ";");
  $("<style>").prop("type", "text/css").html(rule + css).appendTo("head");
}

Использование:

addCssRule(".friend a, .parent a", {
  color: "green",
  "font-size": "20px"
});

Я не уверен, охватывает ли он все возможности CSS, но пока он работает для меня. Если это не так, считайте это отправной точкой для ваших собственных нужд. :)

sjngm
источник
7

Если вы не хотите жестко закодировать CSS в блок / файл CSS, вы можете использовать jQuery для динамического добавления CSS в элементы HTML, идентификаторы и классы.

$(document).ready(function() {
  //Build your CSS.
  var body_tag_css = {
    "background-color": "#ddd",
    "font-weight": "",
    "color": "#000"
  }
  //Apply your CSS to the body tag.  You can enter any tag here, as
  //well as ID's and Classes.
  $("body").css(body_tag_css);
});
Майк Трпчич
источник
5
Этот ответ не совсем то, что просил спрашивающий. Аскер хотел создать правило CSS во время выполнения, а не устанавливать стиль определенного элемента для постоянного объявления CSS.
Дан Даскалеску
Я понимаю, но это альтернативное решение, поэтому я его предоставил.
Майк Трпчич
2
@MikeTrpcic Проблема в том, что есть другие люди, которые тоже ищут это решение - чтобы добавить правила CSS на страницу - и ваш ответ не решает эту проблему.
Нейт
5

Добавление пользовательских правил полезно, если вы создаете виджет jQuery, для которого требуется пользовательский CSS (например, расширение существующей структуры CSS jQueryUI для вашего конкретного виджета). Это решение основано на ответе Тараса (первый выше).

Предполагая, что ваша HTML-разметка имеет кнопку с идентификатором «addrule» и div с идентификатором «target», содержащим некоторый текст:

Код JQuery:

$( "#addrule" ).click(function () { addcssrule($("#target")); });

function addcssrule(target) 
{ 
var cssrules =  $("<style type='text/css'> </style>").appendTo("head");

cssrules.append(".redbold{ color:#f00; font-weight:bold;}"); 
cssrules.append(".newfont {font-family: arial;}"); 
target.addClass("redbold newfont");     
}       

Преимущество этого подхода заключается в том, что вы можете повторно использовать переменные cssrules в своем коде, чтобы добавлять или вычитать правила по желанию. Если cssrules встроен в постоянный объект, такой как виджет jQuery, у вас есть постоянная локальная переменная для работы.

fbloggs
источник
Какая хорошая идея! Я использовал его вместе с фрагментом на этой странице ssdtutorials.com/tutorials/title/jquery-flashing-text.html, чтобы разрешить переключение цвета (оригинал будет переключать только класс). Спасибо!
bgmCoder
5

Обратите внимание, что jQuery().css()это не меняет правила таблицы стилей, оно просто меняет стиль каждого соответствующего элемента.

Вместо этого я написал функцию javascript для изменения самих правил таблицы стилей.

    /**
     * Modify an existing stylesheet.
     * - sheetId - the id of the <link> or <style> element that defines the stylesheet to be changed
     * - selector - the id/class/element part of the rule.  e.g. "div", ".sectionTitle", "#chapter2"
     * - property - the CSS attribute to be changed.  e.g. "border", "font-size"
     * - value - the new value for the CSS attribute.  e.g. "2px solid blue", "14px"
     */
    function changeCSS(sheetId, selector, property, value){
        var s = document.getElementById(sheetId).sheet;
        var rules = s.cssRules || s.rules;
        for(var i = rules.length - 1, found = false; i >= 0 && !found; i--){
            var r = rules[i];
            if(r.selectorText == selector){
                r.style.setProperty(property, value);
                found = true;
            }
        }
        if(!found){
            s.insertRule(selector + '{' + property + ':' + value + ';}', rules.length);
        }
    }

Преимущества:

  • Стили могут быть вычислены в <head>сценарии до того, как будут созданы элементы DOM, и, следовательно, до первого рендеринга документа, избегая визуально раздражающего рендеринга, затем вычисляя, а затем перерисовывая. С помощью jQuery вам придется ждать создания элементов DOM, а затем изменять их стиль и повторную визуализацию.
  • К элементам, которые добавляются динамически после рестайла, автоматически применяются новые стили без дополнительного вызова jQuery(newElement).css()

Предостережения:

  • Я использовал его на Chrome и IE10. Я думаю, что может потребоваться небольшая модификация, чтобы он хорошо работал на старых версиях IE. В частности, старые версии IE, возможно, не s.cssRulesопределились, поэтому они будут s.rulesиметь некоторые особенности, такие как нечетное / ошибочное поведение, связанное с селекторами, разделенными запятыми, например "body, p". Если вы избегаете этого, вы можете быть в порядке в старых версиях IE без изменений, но я еще не проверял это.
  • В настоящее время селекторы должны точно соответствовать: используйте строчные буквы и будьте осторожны со списками, разделенными запятыми; порядок должен совпадать, и они должны быть в формате, "first, second"то есть разделитель - запятая, за которой следует пробел.
  • Вероятно, можно было бы потратить на это дополнительное время, пытаясь обнаружить и разумно обработать перекрывающиеся селекторы, например, в списках, разделенных запятыми.
  • Можно также добавить поддержку медиа-запросов и !importantмодификатор без особых проблем.

Если вы хотите внести некоторые улучшения в эту функцию, вы найдете несколько полезных документов по API здесь: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet

Craig
источник
5

В (необычных) случаях, когда вы хотите часто иметь возможность динамически изменять стили - например, приложение для создания тем - добавление тегов <style> или вызов CSSStyleSheet.insertRule () приведет к растущей таблице стилей, которая может иметь производительность и дизайн отладочные последствия.

Мой подход допускает только одно правило для каждого селектора / свойства, очищая все существующие при установке любого правила. API прост и гибок:

function addStyle(selector, rulename, value) {
    var stylesheet = getAppStylesheet();
    var cssRules = stylesheet.cssRules || stylesheet.rules;
    var rule = stylesheet.insertRule(selector + ' { ' + rulename + ':' + value + ';}', cssRules.length);
}

function clearStyle(selector, rulename) {
    var stylesheet = getAppStylesheet();
    var cssRules = stylesheet.cssRules || stylesheet.rules;
    for (var i=0; i<cssRules.length; i++) {
        var rule = cssRules[i];
        if (rule.selectorText == selector && rule.style[0] == rulename) {
            stylesheet.deleteRule(i);
            break;
        }
    }       
}

function addStyles(selector, rules) {
    var stylesheet = getAppStylesheet();
    var cssRules = stylesheet.cssRules || stylesheet.rules;
    for (var prop in rules) {
        addStyle(selector, prop, rules[prop]);
    }
}

function getAppStylesheet() {
    var stylesheet = document.getElementById('my-styles');
    if (!stylesheet) {
        stylesheet = $('<style id="my-styles">').appendTo('head')[0];
    }
    stylesheet = stylesheet.sheet;
    return stylesheet;
}

Использование:

addStyles('body', {
    'background-color': 'black',
    color: 'green',
    margin: 'auto'
});

clearStyle('body', 'background-color');
addStyle('body', 'color', '#333')
Джейсон Бойд
источник
3

Что если вы динамически написали раздел <script> на своей странице (с вашими динамическими правилами), а затем использовали jQuerys .addClass (class) для добавления этих динамически создаваемых правил?

Я не пробовал это, просто предлагая теорию, которая могла бы работать.

Брайан Денни
источник
швы лучше всего прямо сейчас. Я нашел что-то jQuery.cssRule, но это какой-то плагин: - /
Стефан
2
$ ("head"). append ($ ("<style type = 'text / css'> ... в одну сторону
Стефан
2

Немного ленивый ответ на это, но может помочь следующая статья: http://www.javascriptkit.com/dhtmltutors/externalcss3.shtml

Кроме того, попробуйте ввести "изменить правила CSS" в Google

Не уверен, что произойдет, если вы попытаетесь обернуть document.styleSheets [0] с помощью jQuery (), хотя вы можете попробовать

Джеймс Уайзман
источник
2

Вы можете использовать плагин cssRule . Код был прост тогда:

$.cssRule("#my-window {
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}");

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

Роберт Гоуленд
источник
@ Даниэль, да, это так; заявление удалено.
Роберт Гоуленд
Кажется, не поддерживает правило, как это:div:before{content:'name: ';}
liuyanghejerry
2

Вот установка, которая дает команду над цветами с этим объектом JSON

 "colors": {
    "Backlink": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Blazer": ["rgb(240,240,240)"],
    "Body": ["rgb(192,192,192)"],
    "Tags": ["rgb(182,245,245)","rgb(0,0,0)"],
    "Crosslink": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Key": ["rgb(182,245,182)","rgb(0,118,119)"],
    "Link": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Link1": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Link2": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Manager": ["rgb(182,220,182)","rgb(0,118,119)"],
    "Monitor": ["rgb(255,230,225)","rgb(255,80,230)"],
    "Monitor1": ["rgb(255,230,225)","rgb(255,80,230)"],
    "Name": ["rgb(255,255,255)"],
    "Trail": ["rgb(240,240,240)"],
    "Option": ["rgb(240,240,240)","rgb(150,150,150)"]
  }

эта функция

 function colors(fig){
    var html,k,v,entry,
    html = []
    $.each(fig.colors,function(k,v){
        entry  = "." + k ;
        entry += "{ background-color :"+ v[0]+";";
        if(v[1]) entry += " color :"+ v[1]+";";
        entry += "}"
        html.push(entry)
    });
    $("head").append($(document.createElement("style"))
        .html(html.join("\n"))
    )
}

производить этот элемент стиля

.Backlink{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Blazer{ background-color :rgb(240,240,240);}
.Body{ background-color :rgb(192,192,192);}
.Tags{ background-color :rgb(182,245,245); color :rgb(0,0,0);}
.Crosslink{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Key{ background-color :rgb(182,245,182); color :rgb(0,118,119);}
.Link{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Link1{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Link2{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Manager{ background-color :rgb(182,220,182); color :rgb(0,118,119);}
.Monitor{ background-color :rgb(255,230,225); color :rgb(255,80,230);}
.Monitor1{ background-color :rgb(255,230,225); color :rgb(255,80,230);}
.Name{ background-color :rgb(255,255,255);}
.Trail{ background-color :rgb(240,240,240);}
.Option{ background-color :rgb(240,240,240); color :rgb(150,150,150);}
Крис Глейзер
источник
1

если вы не хотите назначать отображение: none классу css, правильный подход - добавить стиль, jQuery.Rule сделает эту работу.

В некоторых случаях вы хотите применить стиль перед событием добавления контента ajax и исчезнуть после добавления, и это все!

Маттиа
источник
1

Здесь у вас есть функция для получения полного определения класса CSS:

getCSSStyle = function (className) {
   for (var i = 0; i < document.styleSheets.length; i++) {
       var classes = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
       for (var x = 0; x < classes.length; x++) {
           if (classes[x].selectorText  && - 1 != classes[x].selectorText.indexOf(className)) {
               return classes[x].cssText || classes[x].style.cssText;
           }
       }
   }
   return '';
};
berniecc
источник
1

Вы можете использовать эту библиотеку под названием cssobj

var result = cssobj({'#my-window': {
  position: 'fixed',
  zIndex: '102',
  display:'none',
  top:'50%',
  left:'50%'
}})

В любое время вы можете обновить свои правила следующим образом:

result.obj['#my-window'].display = 'block'
result.update()

Тогда вы изменили правило. JQuery не библиотека, делающая это.

Джеймс Ян
источник
0

В последнее время я кое-что испортил и использовал два разных подхода при программировании сайта для iPhone / iPod.

Первый способ, с которым я столкнулся при поиске изменений ориентации, чтобы вы могли видеть, является ли телефон портретным или альбомным, это очень статичный, но простой и умный способ:

В CSS:

#content_right,
#content_normal{
 display:none;
}

В файле JS:

function updateOrientation(){
  var contentType = "show_";
  switch(window.orientation){
   case 0:
   contentType += "normal";
   break;

   case -90:
   contentType += "right";
   break; document.getElementById("page_wrapper").setAttribute("class",contentType);
}

В PHP / HTML (сначала импортируйте свой JS-файл, затем в тег body):

<body onorientationchange="updateOrientation();">

Это в основном выбирает другой предварительно установленный блок CSS для запуска в зависимости от результата, возвращаемого из файла JS.

Также более динамичным способом, который я предпочел, было очень простое дополнение к тегу скрипта или вашему файлу JS:

document.getelementbyid(id).style.backgroundColor = '#ffffff';

Это работает для большинства браузеров, но для IE лучше убрать боеприпасы с чем-то более жестким:

var yourID = document.getelementbyid(id); 
 if(yourID.currentstyle) { 
  yourID.style.backgroundColor = "#ffffff";      // for ie :@ 
 } else { 
  yourID.style.setProperty("background-color", "#ffffff");        // everything else :)
 }

Или вы можете использовать getElementByClass()и изменять диапазон предметов.

Надеюсь это поможет!

Ash.

ясень
источник
-2

Может быть, вы можете поместить информацию о стиле в отдельный класс в вашем CSS-файле, например:

.specificstyle {
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}

а затем использовать jQuery в точке вашего выбора, чтобы добавить это имя класса к элементу?

JorenB
источник
1
и вы не хотите помещать информацию в разделе заголовка вашей страницы (между тегами стиля)?
JorenB
-2

Вы можете просто создать класс css, называемый чем-то вроде .fixed-object, в котором есть все ваши css ...

.fixed-object{
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}

Тогда в jquery в любое время вы хотите, чтобы что-то имело этот стиль, просто добавьте к нему этот класс ...

$(#my-window).addClass('fixed-object');

Это кажется самым простым способом сделать это, если я не понимаю, что вам нужно сделать.

Сэр Дэвид Ли
источник
-9

Используя .addClass () в jquery, мы можем динамически добавлять стиль к элементам на странице. например. у нас есть стиль

.myStyle
{
  width:500px;
  height:300px;
  background-color:red;
 }

Теперь в состоянии готовности jquery мы можем добавить CSS как .addClass (myStyle)

Авинаш
источник