Как подать заявку! Важно использовать .css ()?

663

У меня возникли проблемы с применением стиля !important. Ive попытался:

$("#elem").css("width", "100px !important");

Это ничего; ни один стиль ширины не применяется. Есть ли способ jQuery-ish применить такой стиль, не перезаписывая cssText (что означало бы, что Id должен сначала разобрать его и т.д.)?

Изменить. Я должен добавить, что у меня есть таблица стилей со стилем !important, которую я пытаюсь переопределить с помощью встроенного стиля !important, поэтому использование .width() и тому подобное не потому что он переопределяется внешним стилем !important.

Кроме того, вычисляется значение, которое переопределяет предыдущее значение , поэтому я не могу просто создать другой внешний стиль.

  • 0
    Стоит отметить, что это на самом деле работает в Chrome (по крайней мере для меня), но не в Firefox.
  • 0
    Это также работает для меня в Chrome 17.x и Safari 5.1.1, но не в FF 8.0.
Показать ещё 8 комментариев

30 ответов

296
Лучший ответ

Думаю, я нашел реальное решение. Я ввел новую функцию:

jQuery.style(name, value, priority);

Вы можете использовать его для получения значений с помощью .style('name') точно так же, как .css('name'), получить CSSStyleDeclaration с помощью .style(), а также установить значения - с возможностью указать приоритет как "важный". См. this.

Demo

var div = $('someDiv');
console.log(div.style('color'));
div.style('color', 'red');
console.log(div.style('color'));
div.style('color', 'blue', 'important');
console.log(div.style('color'));
console.log(div.style().getPropertyPriority('color'));

Здесь вывод:

null
red
blue
important

Функция

(function($) {    
  if ($.fn.style) {
    return;
  }

  // Escape regex chars with \
  var escape = function(text) {
    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
  };

  // For those who need them (< IE 9), add support for CSS functions
  var isStyleFuncSupported = !!CSSStyleDeclaration.prototype.getPropertyValue;
  if (!isStyleFuncSupported) {
    CSSStyleDeclaration.prototype.getPropertyValue = function(a) {
      return this.getAttribute(a);
    };
    CSSStyleDeclaration.prototype.setProperty = function(styleName, value, priority) {
      this.setAttribute(styleName, value);
      var priority = typeof priority != 'undefined' ? priority : '';
      if (priority != '') {
        // Add priority manually
        var rule = new RegExp(escape(styleName) + '\\s*:\\s*' + escape(value) +
            '(\\s*;)?', 'gmi');
        this.cssText =
            this.cssText.replace(rule, styleName + ': ' + value + ' !' + priority + ';');
      }
    };
    CSSStyleDeclaration.prototype.removeProperty = function(a) {
      return this.removeAttribute(a);
    };
    CSSStyleDeclaration.prototype.getPropertyPriority = function(styleName) {
      var rule = new RegExp(escape(styleName) + '\\s*:\\s*[^\\s]*\\s*!important(\\s*;)?',
          'gmi');
      return rule.test(this.cssText) ? 'important' : '';
    }
  }

  // The style function
  $.fn.style = function(styleName, value, priority) {
    // DOM node
    var node = this.get(0);
    // Ensure we have a DOM node
    if (typeof node == 'undefined') {
      return this;
    }
    // CSSStyleDeclaration
    var style = this.get(0).style;
    // Getter/Setter
    if (typeof styleName != 'undefined') {
      if (typeof value != 'undefined') {
        // Set style property
        priority = typeof priority != 'undefined' ? priority : '';
        style.setProperty(styleName, value, priority);
        return this;
      } else {
        // Get style property
        return style.getPropertyValue(styleName);
      }
    } else {
      // Get CSSStyleDeclaration
      return style;
    }
  };
})(jQuery);

См. этот для примеров того, как читать и устанавливать значения CSS. Моя проблема заключалась в том, что я уже установил !important для ширины в моем CSS, чтобы избежать конфликтов с другими CSS темы, но любые изменения, которые я сделал для ширины в jQuery, не будут затронуты, поскольку они будут добавлены в атрибут стиля.

Совместимость

Для установки с приоритетом с помощью функции setProperty В этой статье говорится, что есть поддержка IE 9+ и всех других браузеров. Я попытался с IE 8, и он провалился, поэтому я создал поддержку для него в моих функциях (см. Выше). Он будет работать во всех других браузерах с использованием setProperty, но для этого потребуется мой пользовательский код для работы в < IE 9.

  • 0
    Вы проверяли это в других браузерах?
  • 0
    Посмотрите мои обновления, я встроил поддержку IE8 и ниже, и он отлично работает в IE9 (как указано в ссылках) и, конечно, во всех других браузерах.
Показать ещё 15 комментариев
552

Проблема вызвана тем, что jQuery не понимает атрибут !important и как таковой не применяет правило.

Возможно, вы сможете обойти эту проблему и применить правило, обратившись к нему, через addClass():

.importantRule { width: 100px !important; }

$('#elem').addClass('importantRule');

Или используя attr():

$('#elem').attr('style', 'width: 100px !important');

Однако последний подход отменяет любые ранее установленные правила стиля в строке. Поэтому используйте с осторожностью.

Конечно, есть хороший аргумент в пользу того, что метод @Nick Craver проще/мудрее.

Вышеупомянутый подход attr() слегка изменен, чтобы сохранить исходную строку/свойства style:

$('#elem').attr('style', function(i,s) { return s + 'width: 100px !important;' });
  • 2
    Я склоняюсь к вашему последнему подходу, но что печально, так это то, что плохо, вероятно, в конечном итоге придется анализировать предыдущий cssText, потому что я не могу просто отказаться от него
  • 0
    К вашему сведению, в вашем первом фрагменте вы должны изменить .rule на .importantRule или наоборот.
Показать ещё 13 комментариев
142

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

$("#elem").width(100);

Обновлен для комментариев: У вас есть этот вариант, но он заменит все css на элемент, поэтому не уверен, что он более жизнеспособен:

$('#elem').css('cssText', 'width: 100px !important');
  • 0
    Хорошо, я использовал в качестве примера, что меня волнует, так это настройка! важно.
  • 1
    также я отредактировал вопрос, чтобы лучше отразить мою ситуацию .. в основном у меня есть внешняя! важная ширина, которая установлена на что-то плохое, что я должен переопределить встроенным. width () не работает по этой причине
Показать ещё 3 комментария
61
var elem = $("#elem");
elem[0].style.removeAttribute('width');
elem[0].style.setProperty('width', '100px', 'important');
  • 1
    Может быть, дать некоторые объяснения ...
  • 8
    Это один из лучших ответов. Все просто и работает. И это не требует особых объяснений. Это просто обычный JavaScript, за исключением селектора jQuery. jQuery не обеспечивает поддержку «важных», поэтому использование обычного JS - это путь
Показать ещё 5 комментариев
49

Ответ Дэвида Томаса описывает способ использования $('#elem').attr('style', …), но предупреждает, что его использование удалит ранее установленные стили в атрибуте style. Вот способ использования attr() без этой проблемы:

var $elem = $('#elem');
$elem.attr('style', $elem.attr('style') + '; ' + 'width: 100px !important');

Как функция:

function addStyleAttribute($element, styleAttribute) {
    $element.attr('style', $element.attr('style') + '; ' + styleAttribute);
}
addStyleAttribute($('#elem'), 'width: 100px !important');

Вот JS Bin demo.

  • 2
    addStyleAttribute() также может быть изменен, чтобы принимать те же параметры, что и jQuery .css() . Например, он может поддержать отображение карты свойств CSS на их значения. Если бы вы сделали это, вы бы в основном повторно реализовали .css() с исправленной ошибкой !important но без каких-либо оптимизаций.
  • 1
    Это хорошо работает для меня, так как ширина была определена в классе CSS, и мне нужно было динамически переопределить ее с помощью значения, рассчитанного на основе ширины окна браузера и содержимого.
26

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

$(".selector")[0].style.setProperty( 'style', 'value', 'important' );

Однако это не работает в IE 8 и ниже.

  • 1
    и так как мы все еще должны поддерживать IE8 (некоторым из нас не повезло) - это нехорошо.
22

Вы можете сделать это:

$("#elem").css("cssText", "width: 100px !important;");

Использование "cssText" в качестве имени свойства и того, что вы хотите добавить в CSS в качестве значения.

  • 5
    Недостатком этого является то, что он будет перезаписывать все, что cssText был там раньше - так что вы не можете использовать его свободно
17

Вы можете достичь этого двумя способами:

$("#elem").prop("style", "width: 100px !important"); // this is not supported in chrome
$("#elem").attr("style", "width: 100px !important");
  • 0
    На самом деле, функция .prop() была добавлена в jQuery v1.6 и будет работать в Chrome ... это процитировано со страницы поддержки: До jQuery 1.6 метод .attr() иногда учитывал значения свойств при получении некоторых атрибуты, которые могут вызвать противоречивое поведение. Начиная с jQuery 1.6, метод .prop() предоставляет способ явного получения значений свойств, в то время как .attr() возвращает атрибуты.
  • 1
    Не очень хорошая идея для общего решения. Вы можете переопределить свой существующий стиль, используя это.
14

Нет необходимости идти на сложность ответа @AramKocharyan и не нужно динамически вставлять теги стиля.

Просто перепишите стиль, но вам не нужно ничего разбирать, зачем вам?

// Accepts the hyphenated versions (i.e. not 'cssFloat')
function addStyle(element, property, value, important) {
    // Remove previously defined property
    if (element.style.setProperty)
        element.style.setProperty(property, '');
    else
        element.style.setAttribute(property, '');

    // Insert the new style with all the old rules
    element.setAttribute('style', element.style.cssText +
        property + ':' + value + ((important) ? ' !important' : '') + ';');
}

Нельзя использовать removeProperty(), потому что он не будет удалять !important правила в Chrome.
Невозможно использовать element.style[property] = '', потому что он принимает только camelCase в Firefox.

Вероятно, вы можете сделать это короче с jQuery, но эта функция ванили будет работать в современных браузерах, Internet Explorer 8 и т.д.

  • 0
    Отличная работа, спасибо
12

Вот что я сделал после столкновения с этой проблемой...

var origStyleContent = jQuery('#logo-example').attr('style');
jQuery('#logo-example').attr('style', origStyleContent + ';width:150px !important');
  • 0
    Спасибо, это гораздо проще реализовать, чем пользовательский плагин (даже если он потенциально разрушает другие встроенные стили).
9

Самое простое и лучшее решение этой проблемы у меня было просто использовать addClass() вместо.css() или.attr().

Например:

$('#elem').addClass('importantClass');

И в вашем файле CSS:

.importantClass {
    width: 100px !important;
}
  • 1
    Поскольку ширина вычисляется в JavaScript, это не решает проблему.
9

Это решение не отменяет ни один из предыдущих стилей, он просто применяет тот, который вам нужен:

var heightStyle = "height: 500px !important";
if ($("foo").attr('style')) {
  $("foo").attr('style', heightStyle + $("foo").attr('style').replace(/^height: [-,!,0-9,a-z, A-Z, ]*;/,''));
else {
  $("foo").attr('style', heightStyle);
}
9

Если это не так актуально, и поскольку вы имеете дело с одним элементом, который является #elem, вы можете изменить его id на что-то еще и #elem его по своему усмотрению...

$('#elem').attr('id', 'cheaterId');

И в вашем CSS:

#cheaterId { width: 100px;}
  • 9
    почему вы меняете идентификатор для применения CSS вместо того, чтобы просто добавить класс CSS?
8

Вместо использования функции css() попробуйте функцию addClass():

  <script>
  $(document).ready(function() {
    $("#example").addClass("exampleClass");
  });
  </script>

  <style>
  .exampleClass{
    width:100% !important;
    height:100% !important;
  }
  </style>
  • 0
    ОП написал, что значение свойства рассчитывается динамически, поэтому ваш ответ ему не подходит.
  • 0
    Это решение сработало для меня. Я не думаю, что у меня есть точные потребности в качестве исходного постера, но он работает там, где css () нет.
Показать ещё 1 комментарий
6

FYI, это не работает, потому что jQuery не поддерживает его. В 2012 году был подан билет (# 11173 $(elem).css( "property" , "value! Important" )), который был в конечном итоге закрыт как WONTFIX.

6

Может быть, это выглядит так:

кэш

var node = $('.selector')[0];
OR
var node = document.querySelector('.selector');

Установить CSS

node.style.setProperty('width', '100px', 'important');

Удалить CSS

node.style.removeProperty('width');
OR
node.style.width = '';
6

Альтернативный способ добавления стиля в голову:

$('head').append('<style> #elm{width:150px !important} </style>');

Это добавляет стиль после всех ваших файлов CSS, поэтому он будет иметь более высокий приоритет, чем другие файлы CSS, и будет применяться.

6

Нам нужно сначала удалить предыдущий стиль. Я удаляю его с помощью регулярного выражения. Вот пример изменения цвета:

var SetCssColorImportant = function (jDom, color) {
       var style = jDom.attr('style');
       style = style.replace(/color: .* !important;/g, '');
       jDom.css('cssText', 'color: ' + color + ' !important;' + style); }
  • 3
    Не знаю, почему так много решений взламывают тег стиля на элемент, когда метод cssText работает просто отлично ... например, $selector.css('cssText','margin-bottom: 0 !important')
4

Делай это так:

$("#elem").get(0).style.width= "100px!important";
4

Я бы предположил, что вы пробовали его, не добавляя !important?

Встроенный CSS (как JavaScript добавляет стиль) переопределяет CSS стилей. Я уверен, что дело даже в том случае, когда правило CSS стилей имеет !important.

Другой вопрос (может быть, глупый вопрос, но его нужно спросить.): Является ли элемент, который вы пытаетесь работать на display:block; или display:inline-block; ?

Не зная, что ваш опыт в CSS... встроенные элементы не всегда ведут себя так, как вы ожидали.

  • 4
    Правила CSS, которые имеют! Important, переопределяют все, независимо от того, где они расположены, за исключением того, что встроенные стили с! Важным переопределяют стили таблицы стилей с! Важным. Это проблема, с которой я столкнулся. есть правило таблицы стилей с! важным, что я хотел бы переопределить. Более того, значение, которое я должен предоставить, должно быть вычислено через JS, поэтому я не могу просто изменить саму таблицу стилей.
3

Я думаю, что он работает нормально и может перезаписать любой другой CSS раньше (это: элемент DOM):

this.setAttribute('style', 'padding:2px !important');
3

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

Если, например, вы хотели, чтобы 3-й и 6-й экземпляры .cssText имели другую ширину, которую вы могли бы написать:

.cssText:nth-of-type(3), .cssText:nth-of-type(6) {width:100px !important;}

Или:

.container:nth-of-type(3).cssText, .container:nth-of-type(6).cssText {width:100px !important;}
  • 0
    Это не соответствует 3-му и 6-му экземплярам .cssText . :nth-of-type() не делает то, что вы думаете, он делает. Смотрите здесь для объяснения.
  • 0
    Справедливо. Я прочитал ссылку, но я не уверен, что понял вашу мысль. Вот скрипка, показывающая, что это работает как задумано: jsfiddle.net/d2E4b
Показать ещё 1 комментарий
2

На мой взгляд, самый простой способ: вы можете сделать (Ex, если вам нужно установить ширину с важным тегом)

$('exampleDiv').css('width', '');
//This will remove the width of the item
var styles = $('exampleDiv').attr('style');
//This will contain all styles in your item
//ex: height:auto; display:block;
styles += 'width: 200px !important;'
//This will add the width to the previous styles
//ex: height:auto; display:block; width: 200px !important;
$('exampleDiv').attr('style', styles);
//This will add all previous styles to your item
2

Три рабочих примера

У меня была аналогичная ситуация, но я использовал.find() после долгого столкновения с.closest() в течение многих времен.

Пример кода

// Allows contain functions to work, ignores case sensitivity

jQuery.expr[':'].contains = function(obj, index, meta, stack) {
    result = false;
    theList = meta[3].split("','");
    var contents = (obj.textContent || obj.innerText || jQuery(obj).text() || '')
    for (x=0; x<theList.length; x++) {
        if (contents.toLowerCase().indexOf(theList[x].toLowerCase()) >= 0) {
            return true;
        }
    }
    return false;
};

$(document).ready(function() {
    var refreshId = setInterval( function() {
        $("#out:contains('foo', 'test456')").find(".inner").css('width', '50px', 'important');
    }, 1000); // Rescans every 1000 ms
});

альтернатива

$('.inner').each(function () {
    this.style.setProperty('height', '50px', 'important');
});

$('#out').find('.inner').css({ 'height': '50px'});

Работа: http://jsfiddle.net/fx4mbp6c/

  • 0
    Я .indexOf() от .indexOf() голосования, но вы должны заменить .indexOf() на что-то более совместимое с браузерами. Вместо этого используйте .match() или .test() вместо .indexOf()
  • 0
    Почему нет точки с запятой в строке с var contents = ?
2

У меня была та же проблема, которая пыталась изменить цвет текста элемента меню, когда "событие". Лучший способ, который я нашел, когда у меня возникла такая же проблема:

Первый шаг: создайте в своем CSS новый класс с этой целью, например:

.colorw{ color: white !important;}

Последний шаг: применить этот класс с помощью метода addClass следующим образом:

$('.menu-item>a').addClass('colorw');

Задача решена.

  • 0
    Лучший ответ, на мой взгляд. Самый удобный.
  • 0
    Спасибо @Siyah CSS известен множеству людей, но понимается только для немногих, и это печально и заставляет некоторых программистов ненавидеть это.
2

Мы можем использовать setProperty или cssText для добавления !important для элемента DOM с использованием JavaScript.

Пример 1:

elem.style.setProperty ("color", "green", "important");

Пример 2:

elem.style.cssText='color: red !important;'
2

Я также обнаружил, что некоторые элементы или надстройки (например, Bootstrap) имеют некоторые особые случаи, когда они не хорошо работают с !important или другими обходами, например .addClass/.removeClass, и поэтому вам нужно их переключать вкл выкл.

Например, если вы используете что-то вроде <table class="table-hover">, единственный способ успешно изменить элементы, такие как цвета строк, - это включить/выключить класс table-hover, например

$(your_element).closest("table").toggleClass("table-hover");

Надеюсь, эта работа будет полезна кому-то!:)

1

Самым безопасным решением для этого является добавление класса, а затем выполнение магии в CSS :-), addClass() и removeClass() должны выполнить эту работу.

1

https://jsfiddle.net/xk6Ut/256/

Альтернативный подход - это динамическое создание и обновление класса CSS в JavaScript. Для этого мы можем использовать элемент стиля и использовать идентификатор для элемента стиля, чтобы мы могли обновить класс CSS

function writeStyles(styleName, cssText) {
    var styleElement = document.getElementById(styleName);
    if (styleElement) document.getElementsByTagName('head')[0].removeChild(
        styleElement);
    styleElement = document.createElement('style');
    styleElement.type = 'text/css';
    styleElement.id = styleName;
    styleElement.innerHTML = cssText;
    document.getElementsByTagName('head')[0].appendChild(styleElement);
}

...

  var cssText = '.testDIV{ height:' + height + 'px !important; }';
  writeStyles('styles_js', cssText)
-7

Еще один простой способ решить эту проблему, добавив атрибут style:

$('.selector').attr('style', 'width:500px !important');
  • 1
    Проблема с этим решением состоит в том, что оно заменит любые другие стили в атрибуте style вместо простого изменения / добавления свойства width .
Сообщество Overcoder
Наверх
Меню