Как подать заявку! Важно использовать.css()?
У меня проблемы с применением стиля, который !important
, Я пробовал:
$("#elem").css("width", "100px !important");
Это ничего не делает; стиль ширины вообще не применяется. Есть ли способ применения такого стиля в jQuery-иш без необходимости перезаписи cssText
(что означало бы, что мне нужно сначала разобрать его и т. д.)?
Изменить: я должен добавить, что у меня есть таблица стилей с !important
стиль, который я пытаюсь переопределить с !important
стиль встроенный, поэтому с помощью .width()
и тому подобное не работает, так как он переопределяется моим внешним !important
стиль.
Также вычисляется значение, которое переопределяет предыдущее значение, поэтому я не могу просто создать другой внешний стиль.
30 ответов
Я думаю, что нашел реальное решение. Я сделал это в новую функцию:
jQuery.style(name, value, priority);
Вы можете использовать его, чтобы получить значения с .style('name')
как .css('name')
получить CSSStyleDeclaration с .style()
, а также установить значения - с возможностью указать приоритет как "важный". Смотрите это.
демонстрация
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, не будут затронуты, так как они будут добавлены в атрибут style.
Совместимость
Для настройки с приоритетом, используя setProperty
Эта статья говорит, что есть поддержка IE 9+ и всех других браузеров. Я пытался с IE 8, и он потерпел неудачу, поэтому я встроил поддержку для своих функций (см. Выше). Он будет работать во всех других браузерах, использующих setProperty, но для работы в
Проблема вызвана тем, что 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;' });
Вы можете установить ширину напрямую, используя .width()
как это:
$("#elem").width(100);
Обновлено для комментариев: у вас также есть эта опция, но она заменит все CSS на элементе, поэтому не уверен, что он более жизнеспособен:
$('#elem').css('cssText', 'width: 100px !important');
var elem = $("#elem");
elem[0].style.removeAttribute('width');
elem[0].style.setProperty('width', '100px', 'important');
Ответ Дэвида Томаса описывает способ использования $('#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.
Большинство этих ответов уже устарели, поддержка IE7 не является проблемой.
Лучший способ сделать это, поддерживающий IE11+ и все современные браузеры:
const $elem = $("#elem");
$elem[0].style.setProperty('width', '100px', 'important');
Или, если хотите, вы можете создать небольшой плагин jQuery, который сделает это. Этот плагин близко соответствует собственному jQuery.css()
в поддерживаемых параметрах:
/**
* Sets a CSS style on the selected element(s) with !important priority.
* This supports camelCased CSS style property names and calling with an object
* like the jQuery `css()` method.
* Unlike jQuery's css() this does NOT work as a getter.
*
* @param {string|Object<string, string>} name
* @param {string|undefined} value
*/
jQuery.fn.cssImportant = function(name, value) {
const $this = this;
const applyStyles = (n, v) => {
// Convert style name from camelCase to dashed-case.
const dashedName = n.replace(/(.)([A-Z])(.)/g, (str, m1, upper, m2) => {
return m1 + "-" + upper.toLowerCase() + m2;
});
// Loop over each element in the selector and set the styles.
$this.each(function(){
this.style.setProperty(dashedName, v, 'important');
});
};
// If called with the first parameter that is an object,
// Loop over the entries in the object and apply those styles.
if(jQuery.isPlainObject(name)){
for(const [n, v] of Object.entries(name)){
applyStyles(n, v);
}
} else {
// Otherwise called with style name and value.
applyStyles(name, value);
}
// This is required for making jQuery plugin calls chainable.
return $this;
};
// Call the new plugin:
$('#elem').cssImportant('height', '100px');
// Call with an object and camelCased style names:
$('#another').cssImportant({backgroundColor: 'salmon', display: 'block'});
// Call on multiple items:
$('.item, #foo, #bar').cssImportant('color', 'red');
После прочтения других ответов и экспериментов, вот что работает для меня:
$(".selector")[0].style.setProperty( 'style', 'value', 'important' );
Это не работает в IE 8 и ниже, хотя.
Вы можете сделать это:
$("#elem").css("cssText", "width: 100px !important;");
Использование "cssText" в качестве имени свойства и того, что вы хотите добавить в CSS в качестве его значения.
Вы можете достичь этого двумя способами:
$("#elem").prop("style", "width: 100px !important"); // this is not supported in chrome
$("#elem").attr("style", "width: 100px !important");
Нет необходимости вдаваться в сложность ответа @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 и т. Д.
Вот что я сделал после столкновения с этой проблемой...
var origStyleContent = jQuery('#logo-example').attr('style');
jQuery('#logo-example').attr('style', origStyleContent + ';width:150px !important');
Это решение не отменяет ни один из предыдущих стилей, оно просто применяет тот, который вам нужен:
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);
}
Самым простым и лучшим решением для этой проблемы от меня было просто использовать addClass() вместо.css() или.attr().
Например:
$('#elem').addClass('importantClass');
И в вашем файле CSS:
.importantClass {
width: 100px !important;
}
Если это не так актуально и поскольку вы имеете дело с одним элементом, который #elem
, вы можете изменить его идентификатор на что-то другое и стилизовать его как хотите...
$('#elem').attr('id', 'cheaterId');
И в вашем CSS:
#cheaterId { width: 100px;}
Вместо использования css()
Функция попробуйте addClass()
функция:
<script>
$(document).ready(function() {
$("#example").addClass("exampleClass");
});
</script>
<style>
.exampleClass{
width:100% !important;
height:100% !important;
}
</style>
К вашему сведению, это не работает, потому что jQuery не поддерживает его. В 2012 году был подан тикет ( ошибка #11173 $(elem).css("свойство", "значение! Важное")), который в итоге был закрыт как WONTFIX.
Это решение оставит весь вычисленный javascript и добавит важный элемент в элемент: Вы можете сделать это (например, если вам нужно установить ширину с важным тегом)
$('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
Альтернативный способ добавить стиль в голову:
$('head').append('<style> #elm{width:150px !important} </style>');
Это добавляет стиль после всех ваших файлов CSS, поэтому он будет иметь более высокий приоритет, чем другие файлы CSS, и будет применяться.
Сначала нужно удалить предыдущий стиль. Я удаляю это с помощью регулярного выражения. Вот пример для изменения цвета:
var SetCssColorImportant = function (jDom, color) {
var style = jDom.attr('style');
style = style.replace(/color: .* !important;/g, '');
jDom.css('cssText', 'color: ' + color + ' !important;' + style); }
Я думаю, что он работает нормально и может переписать любой другой CSS раньше (это: элемент DOM):
this.setAttribute('style', 'padding:2px !important');
Может быть, это выглядит так:
кэш
var node = $('.selector')[0]; ИЛИ ЖЕ var node = document.querySelector('.selector');
Установить CSS
node.style.setProperty ('ширина', '100px', 'важный');
Удалить CSS
node.style.removeProperty ('ширина'); ИЛИ ЖЕ node.style.width = '';
Сделай это так:
$("#elem").get(0).style.width= "100px!important";
Я предполагаю, что вы попробовали это без добавления !important
?
Встроенный CSS (именно так JavaScript добавляет стилизацию) переопределяет таблицу стилей CSS. Я уверен, что это так, даже если правило CSS таблицы стилей имеет !important
,
Еще один вопрос (возможно, глупый, но его нужно задать.): Элемент, над которым вы пытаетесь работать display:block;
или же display:inline-block;
?
Не зная вашего опыта в CSS... встроенные элементы не всегда ведут себя так, как вы ожидаете.
Три рабочих примера
У меня была похожая ситуация, но я использовал.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/
Это может или не может быть подходящим для вашей ситуации, но вы можете использовать селекторы 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;}
Мы можем использовать setProperty или cssText, чтобы добавить !important
к элементу DOM, используя JavaScript.
Пример 1:
elem.style.setProperty ("color", "green", "important");
Пример 2:
elem.style.cssText='color: red !important;'
Я также обнаружил, что некоторые элементы или надстройки (например, Bootstrap) имеют особые классы, в которых они не очень хорошо работают. !important
или другие обходные пути, такие как .addClass/.removeClass
и, следовательно, вы должны включить / выключить их.
Например, если вы используете что-то вроде <table class="table-hover">
единственный способ успешно изменить элементы, такие как цвета строк, это переключить table-hover
класс вкл / выкл, вот так
$(your_element).closest("table").toggleClass("table-hover");
Надеюсь, этот обходной путь будет полезен кому-то!:)
Самый безопасный обходной путь - добавить класс, а затем сделать магию в CSS:-), addClass()
а также removeClass()
должен сделать работу.
У меня была такая же проблема, когда я пытался изменить цвет текста пункта меню, когда "событие". Лучший способ, который я нашел, когда у меня была такая же проблема:
Первый шаг: создайте в своем CSS новый класс с этой целью, например:
.colorw{ color: white !important;}
Последний шаг: примените этот класс, используя метод addClass следующим образом:
$('.menu-item>a').addClass('colorw');
Задача решена.
https://jsfiddle.net/xk6Ut/256/
Альтернативный подход - динамическое создание и обновление класса CSS в JavaScript. Чтобы сделать это, мы можем использовать элемент style и нам нужно использовать ID для элемента style, чтобы мы могли обновить класс 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)