Расширьте функцию jquery.css, чтобы переопределить важные стили
Я пишу редактор шаблонов почты, пользователи могут импортировать свои существующие шаблоны и перепроектировать шаблон с помощью нашего визуального редактора. Если элемент, измененный пользователем, имеет свойство стиля ! Important; мы должны переопределить свойство с помощью jquery.css.
Пример:
<div id="sendwrapper">
<button> Send </button>
</div>
Стиль
#sendwrapper * {
color:white !important;
}
Я хочу изменить цвет белый на зеленый. Я пробовал этот плагин https://github.com/premasagar/important/blob/master/important.js. Этот плагин не настолько умен, что он устанавливает ! Important для всех свойств, но я ожидаю, что он должен установить ! Important только для свойств, которые устанавливают ! Important.
Ответы
Ответ 1
Если браузер поддерживает Proxy
(ES6), вы можете использовать этот плагин:
if ( // Check browser support
window.Proxy
&& window.CSSStyleDeclaration
&& CSSStyleDeclaration.prototype.setProperty
) {
jQuery.cssHooks = new Proxy(jQuery.cssHooks, {
get: function(hooks, name) {
return new Proxy(hooks[name] || (hooks[name] = {}), {
has: function (hook, setget) {
return setget === 'set' || setget in hook;
},
get: function (hook, setget){
if(setget !== 'set') return hook[setget];
return function(elem, value, extra) {
// Use the cssHook setter, if any
if(hook.set) {
value = hook.set(elem, value, extra);
if(value === void 0) return; // No value
}
// Set the desired value without !important
elem.style[ name ] = value;
// Get the computed value
var computedValue = jQuery.css(elem, name);
// Check if the computed value is the desired one
if(computedValue === value) return; // OK
// Set the desired value with !important
elem.style.setProperty(name, value, "important");
// Check if the computed value has changed
if(computedValue !== jQuery.css(elem, name)) return; // OK
// Otherwise !important is not needed, so remove it
elem.style.setProperty(name, value);
}
}
});
}
});
}
// Plugin compiled with Closure Compiler
window.Proxy&&window.CSSStyleDeclaration&&CSSStyleDeclaration.prototype.setProperty&&(jQuery.cssHooks=new Proxy(jQuery.cssHooks,{get:function(f,b){return new Proxy(f[b]||(f[b]={}),{has:function(b,a){return"set"===a||a in b},get:function(e,a){return"set"!==a?e[a]:function(d,c,a){if(e.set&&(c=e.set(d,c,a),void 0===c))return;d.style[b]=c;a=jQuery.css(d,b);a!==c&&(d.style.setProperty(b,c,"important"),a===jQuery.css(d,b)&&d.style.setProperty(b,c))}}})}}));
// The elements in the collection that need !important will use it
$('.color').css('color', 'blue');
// The plugin is compatible with custom cssHooks
$.cssHooks.opacity.set = function(elem, value) { return value/4 + '' };
$('.opacity').css('opacity', .8);
.color {
color: red;
}
.color.important {
color: red !important;
}
.opacity.important {
opacity: 1 !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="color">color: blue</div>
<div class="color important">color: blue !important</div>
<div class="opacity important">opacity: .2 !important</div>
Ответ 2
Не нужно использовать слишком много компилируемого кода. jquery предоставляет вам возможность перезаписывать правило CSS.
Просто используйте это
$('#sendwrapper').children().css("cssText", "color: green !important;");
Я использую children()
, потому что, как я вижу, вы применили свой css следующим образом: #sendwrapper *
Итак, чтобы рассмотреть *
, я использую children()
.
И cssText
просто перезапишите текущий CSS
А также тот тип модуля, который вы создаете, это наилучший подход.
DEMO: http://jsfiddle.net/6L0p5gk9/
Поэтому нет необходимости расширять функцию jQuery
CSS
. Функциональность, которую вы ищете, уже существует
Ответ 3
В определении jQuery.style
(поиск style:
в исходном коде) найдите строку
style[ name ] = value;
После этого добавьте этот код:
// Get the computed value after setting the desired value without !important
var computedValue = jQuery.css(elem, name);
// Check if browser supports adding inline important styles
if(typeof style.setProperty == 'function') {
// Set the desired value with !important
style.setProperty(name, value, "important");
// Check if the computed value is still the same
if(computedValue === jQuery.css(elem, name)) {
// Then !important is not needed, so remove it
style.setProperty(name, value);
}
}
Ответ 4
Я написал плагин, который сначала пытается добавить желаемое правило, если ничего не изменилось, он добавляет правило с !important
. Насколько мне известно, нет способа тестирования, если для правила установлено значение !important
, но если значение не изменяется при попытке изменить его с помощью JS, вы можете предположить, что это случай.
Короче говоря, он устанавливает важное объявление только в случае необходимости:
$.fn.extend({
cssi:function(obj){
var $target=this;
$.each(obj,function(i,e){
var initialVal=$target.css(i);
$target.css(i,e);
if($target.css(i)===initialVal && initialVal!==e){ //add !important only if the value didn't change and you're not trying to set it to the value it already had
if(!isNaN(e)) e+="px";
e+=" !important";
$target.css(i,""); // clear any prior rules
$target[0].style.cssText+=camelToDash(i)+":"+e;
}
});
return this;
}
});
function camelToDash(str) {
return str.replace(/\W+/g, '-')
.replace(/([a-z\d])([A-Z])/g, '$1-$2')
.toLowerCase();
}
//Demo
$(function(){
$("div").cssi({
backgroundColor:"blue",
height:100,
width:100,
color:"red"
});
});
div{ /*Just something to test it with*/
height: 50px !important;
width:50px;
background-color:red !important;
color:green !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Hello world!</div>
Ответ 5
//Очистить! important css
$('#elementToChange').css('background-color', '');
$('#elementToChange').css('background-color', 'blue');
Или в одном слое:
$('#elementToChange')
.css('background-color', '')
.css('background-color', 'blue');
Или вы можете добавить к нему класс по предопределенному классу в вашем css.