Is it possible to read the class values of the style's part from script part in vue?
e.g I have:
.node-output02 {
bottom: #{-2+$portSize/-2}px;
left: #{$nodeWidth/3}px;
}
in script I want to do:
const left = .node-output02.left
Is it possible to read the class values of the style's part from script part in vue?
e.g I have:
.node-output02 {
bottom: #{-2+$portSize/-2}px;
left: #{$nodeWidth/3}px;
}
in script I want to do:
const left = .node-output02.left
This is less of a Vue issue and more of a general JS issue.
Using this code (for obtaining the CSS text from a stylesheet), you can parse the CSS into a query-able object.
It's not fool-proof, but it's a start.
console.log('left =', getStyleObject('.node-output02')['left']); // 420px
function getStyleText(className) {
let classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules,
styleText = '';
Array.from(classes).forEach(clazz => {
if (clazz.selectorText == className) {
styleText += clazz.cssText || clazz.style.cssText;
}
});
return styleText;
}
function getStyleObject(className) {
let styleText = getStyleText(className);
if (styleText.length > 0) {
let leftBraceIndex = styleText.indexOf('{'),
rightBraceIndex = styleText.lastIndexOf('}'),
selector = styleText.substring(0, leftBraceIndex).trim(),
ruleText = styleText.substring(leftBraceIndex + 1, rightBraceIndex).trim();
return Object.fromEntries(ruleText.split(/\s*;\s*/g)
.filter(v => v.length > 0) // filter out empty (if there is a trailing semi-colon)
.map(v => v.split(/\s*:\s*/g)));
}
return null;
}
.node-output02 {
bottom: 360px;
left: 420px;
}
In the example below, everything is merged top-to-bottom, but !important
is ignored, a reducer might be a better option.
console.log('left =', getStyleObject('.node-output02')['left']); // 100%;
function getStyleText(className) {
let classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules,
styles = [];
Array.from(classes).forEach(clazz => {
if (clazz.selectorText == className) {
let styleText = clazz.cssText || clazz.style.cssText,
leftBraceIndex = styleText.indexOf('{'),
rightBraceIndex = styleText.lastIndexOf('}'),
selector = styleText.substring(0, leftBraceIndex).trim(),
ruleText = styleText.substring(leftBraceIndex + 1, rightBraceIndex).trim();
styles.push(ruleText);
}
});
return styles;
}
function getStyleObject(className) {
return Object.assign.apply({}, getStyleText(className).map(ruleText => {
return Object.fromEntries(ruleText.split(/\s*;\s*/g)
.filter(v => v.length > 0)
.map(v => v.split(/\s*:\s*/g)));
}));
}
.node-output02 {
bottom: 360px;
left: 420px;
}
.node-output02 {
left: 5em !important; /* This should precedence... */
}
.node-output02 {
left: 100%; /* This will be the returned value. */
}
If you want to maintain precedence, you can identify !important
exceptions.
Again, this is not fool-proof, because selector specificity is not maintained either. But it is more robust than the code above.
console.log('left =', getStyleObject('.node-output02')['left']); // 5em
function getStyleText(className) {
let classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules,
styles = [];
Array.from(classes).forEach(clazz => {
if (clazz.selectorText == className) {
let styleText = clazz.cssText || clazz.style.cssText,
leftBraceIndex = styleText.indexOf('{'),
rightBraceIndex = styleText.lastIndexOf('}'),
selector = styleText.substring(0, leftBraceIndex).trim(),
ruleText = styleText.substring(leftBraceIndex + 1, rightBraceIndex).trim();
styles.push(ruleText);
}
});
return styles;
}
function getStyleObject(className) {
return cleanupValues(getStyleText(className).reduce((result, ruleText) => {
let css = parseRuleText(ruleText);
for (let [prop, value] of Object.entries(css)) {
if (result.hasOwnProperty(prop) &&
result[prop].includes('!important') &&
!value.includes('!important')) {
continue; // ignore...
}
result[prop] = value;
}
return result;
}, {}));
}
function parseRuleText(ruleText) {
return Object.fromEntries(ruleText.split(/\s*;\s*/g)
.filter(v => v.length > 0)
.map(v => v.split(/\s*:\s*/g)));
}
function cleanupValues(css) {
for (let [prop, value] of Object.entries(css)) {
if (value.includes('!important')) {
css[prop] = value.replace(/\s*!important/, '');
}
}
return css;
}
.node-output02 {
bottom: 360px;
left: 420px;
}
.node-output02 {
left: 5em !important; /* This will be the returned value. */
}
.node-output02 {
left: 100%; /* Not as important as the preceeding rule. */
}