在样式属性中使用 CSS 选择器
Using CSS selectors within the style attribute
我有一个漂亮的小按钮,它使用了很多花哨的东西 CSS 看起来不错。
这是它背后的代码(我暂时忽略兼容性问题);如您所见,它使用一些选择器来处理悬停和点击事件。
.button {
display: inline-block;
width: 200px;
height: 200px;
padding: 15px;
border-radius: 25px;
background:linear-gradient(to bottom, hsla(36, 100%, 60%, 1) 5%, hsla(36, 100%, 40%, 1) 100%);
border:2px solid hsla(36, 100%, 30%, 1);
box-shadow:inset 0px 2px 2px 0px white;
position: relative;
left: 0px;
top: 0px;
text-shadow:0px 1px 0px hsla(36, 100%, 30%, 1);
margin: 25px;
}
.button:hover {
background:linear-gradient(to bottom, hsla(36, 100%, 65%, 1) 5%, hsla(36, 100%, 45%, 1) 100%);
}
.button:active {
background:linear-gradient(to bottom, hsla(36, 100%, 40%, 1) 5%, hsla(36, 100%, 60%, 1) 100%);
}
但是,为了在将来有很多按钮时简化流程,我反而希望能够使按钮具有颜色的自定义属性(下面的 buttonColor
),它将被读取一些 JavaScript,变成了 Hue/Saturation/Lightness,并最终改变了许多不同的变体。每个按钮至少包含三种颜色;两个用于渐变,一个用于投影和边框。
<div class="button" id="testButton"buttonColor="ff8c00">
<p class="buttonHeader">foo</p>
<p class="buttonBody">foo2</p>
</div>
这是我在 JavaScript 中得到的:
function hexToRgb(hex) { //converts hexadecimal colors into Red/Green/Blue
//code omitted for sake of conciseness
return [r, g, b];
}
function rgbToHsl(r, g, b) { //converts Red/Green/Blue into Hue/Saturation/Lightness
//ditto
return [h, s, l]
}
var buttons = document.body.getElementsByClassName('button'); //Gets all elements with button class
for (var i = 0; i < buttons.length; i++) {
var rgb = hexToRgb(buttons[i].getAttribute("buttoncolor")); //
var hsl = rgbToHsl(rgb.r, rgb.g, rgb.b)
//here
}
这就是我卡住的地方。
我可以很容易地修改按钮的样式,但只能在它处于非活动状态时;我发现无法改变它在 :hover 和 :active 选择器下的反应方式。
使用数据属性!尝试这样的事情:
<div class="button" id="testButton" data-button-color="ff8c00">
<p class="buttonHeader">foo</p>
<p class="buttonBody">foo2</p>
</div>
js
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
var buttons = document.body.getElementsByClassName('button'); //Gets all elements with button class
for (var i = 0; i < buttons.length; i++) {
var rgb = hexToRgb(buttons[i].data("button-color")),
hsl = rgbToHsl(rgb.r, rgb.g, rgb.b),
rules = [];
rules[i][0] = hsl;
hsl[2] = 100 - hsl[2]; // make second color
rules[i][1] = hsl;
var len = rules.length;
for(;len--;) {
buttons[i].style =
"background: linear-gradient(to bottom, hsla(36, 100%, "+rules[i][0]+"%, 1) 5%, hsla(36, 100%, "+rules[i][1]+"%, 1) 100%);"; // put rules on el
}
}
编辑
David Walsh 在 adding rules to stylesheets with js 上有出色的 post。
假设您创建了一个规则数组
var rules = [...]; // ['float: left', 'cursor: pointer']
或对象
var rules = {
'hover': [...], // rules...
'active': [...]
};
在你上面的代码中。然后您可以使用以下内容插入它们:
var sheet = (function() {
var style = document.createElement("style");
style.appendChild(document.createTextNode(""));
document.head.appendChild(style);
return style.sheet;
})();
function addCSSRule(sheet, selector, rules, index) {
if("insertRule" in sheet) {
sheet.insertRule(selector + "{" + rules + "}", index);
}
else if("addRule" in sheet) {
sheet.addRule(selector, rules, index);
}
}
// ['float: left', 'cursor: pointer']
addCSSRules(document.styleSheets[0], ".button:hover", rules.join(';'));
或
// { 'hover': ['float: left'], 'active': ['cursor: pointer']};
addCSSRules(document.styleSheets[0], ".button:hover", rules.hover.join(';'));
addCSSRules(document.styleSheets[0], ".button:active", rules.active.join(';'));
我有一个漂亮的小按钮,它使用了很多花哨的东西 CSS 看起来不错。
这是它背后的代码(我暂时忽略兼容性问题);如您所见,它使用一些选择器来处理悬停和点击事件。
.button {
display: inline-block;
width: 200px;
height: 200px;
padding: 15px;
border-radius: 25px;
background:linear-gradient(to bottom, hsla(36, 100%, 60%, 1) 5%, hsla(36, 100%, 40%, 1) 100%);
border:2px solid hsla(36, 100%, 30%, 1);
box-shadow:inset 0px 2px 2px 0px white;
position: relative;
left: 0px;
top: 0px;
text-shadow:0px 1px 0px hsla(36, 100%, 30%, 1);
margin: 25px;
}
.button:hover {
background:linear-gradient(to bottom, hsla(36, 100%, 65%, 1) 5%, hsla(36, 100%, 45%, 1) 100%);
}
.button:active {
background:linear-gradient(to bottom, hsla(36, 100%, 40%, 1) 5%, hsla(36, 100%, 60%, 1) 100%);
}
但是,为了在将来有很多按钮时简化流程,我反而希望能够使按钮具有颜色的自定义属性(下面的 buttonColor
),它将被读取一些 JavaScript,变成了 Hue/Saturation/Lightness,并最终改变了许多不同的变体。每个按钮至少包含三种颜色;两个用于渐变,一个用于投影和边框。
<div class="button" id="testButton"buttonColor="ff8c00">
<p class="buttonHeader">foo</p>
<p class="buttonBody">foo2</p>
</div>
这是我在 JavaScript 中得到的:
function hexToRgb(hex) { //converts hexadecimal colors into Red/Green/Blue
//code omitted for sake of conciseness
return [r, g, b];
}
function rgbToHsl(r, g, b) { //converts Red/Green/Blue into Hue/Saturation/Lightness
//ditto
return [h, s, l]
}
var buttons = document.body.getElementsByClassName('button'); //Gets all elements with button class
for (var i = 0; i < buttons.length; i++) {
var rgb = hexToRgb(buttons[i].getAttribute("buttoncolor")); //
var hsl = rgbToHsl(rgb.r, rgb.g, rgb.b)
//here
}
这就是我卡住的地方。
我可以很容易地修改按钮的样式,但只能在它处于非活动状态时;我发现无法改变它在 :hover 和 :active 选择器下的反应方式。
使用数据属性!尝试这样的事情:
<div class="button" id="testButton" data-button-color="ff8c00">
<p class="buttonHeader">foo</p>
<p class="buttonBody">foo2</p>
</div>
js
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
var buttons = document.body.getElementsByClassName('button'); //Gets all elements with button class
for (var i = 0; i < buttons.length; i++) {
var rgb = hexToRgb(buttons[i].data("button-color")),
hsl = rgbToHsl(rgb.r, rgb.g, rgb.b),
rules = [];
rules[i][0] = hsl;
hsl[2] = 100 - hsl[2]; // make second color
rules[i][1] = hsl;
var len = rules.length;
for(;len--;) {
buttons[i].style =
"background: linear-gradient(to bottom, hsla(36, 100%, "+rules[i][0]+"%, 1) 5%, hsla(36, 100%, "+rules[i][1]+"%, 1) 100%);"; // put rules on el
}
}
编辑
David Walsh 在 adding rules to stylesheets with js 上有出色的 post。
假设您创建了一个规则数组
var rules = [...]; // ['float: left', 'cursor: pointer']
或对象
var rules = {
'hover': [...], // rules...
'active': [...]
};
在你上面的代码中。然后您可以使用以下内容插入它们:
var sheet = (function() {
var style = document.createElement("style");
style.appendChild(document.createTextNode(""));
document.head.appendChild(style);
return style.sheet;
})();
function addCSSRule(sheet, selector, rules, index) {
if("insertRule" in sheet) {
sheet.insertRule(selector + "{" + rules + "}", index);
}
else if("addRule" in sheet) {
sheet.addRule(selector, rules, index);
}
}
// ['float: left', 'cursor: pointer']
addCSSRules(document.styleSheets[0], ".button:hover", rules.join(';'));
或
// { 'hover': ['float: left'], 'active': ['cursor: pointer']};
addCSSRules(document.styleSheets[0], ".button:hover", rules.hover.join(';'));
addCSSRules(document.styleSheets[0], ".button:active", rules.active.join(';'));