Accessing class properties from JavaScript code

Can you retrieve the class values of a style element using Vue's script section?

For example:

.node-output02 {
    bottom: #{-2+$portSize/-2}px;
    left: #{$nodeWidth/3}px;
  }

In the script, I'd like to achieve:

const left = .node-output02.left

Answer №1

This seems to be more of a JavaScript issue rather than a Vue specific problem.

If you use this code snippet (which helps in extracting CSS text from a stylesheet), you can convert the CSS into an object that can be queried.

While it may not cover all scenarios, it can serve as a good starting point.

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) 
      .map(v => v.split(/\s*:\s*/g)));
  }
  return null;
}
.node-output02 {
  bottom: 360px;
  left: 420px;
}


Handling Multiple Style Rules...

In the following example, styles are combined top to bottom, but the `!important` flag is ignored. Using a reducer function might be a better approach.

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 take precedence... */
}

.node-output02 {
  left: 100%; /* This will be the final value returned. */
}


Using Reducer Function

If maintaining priority is important, you can handle exceptions with `!important`. However, this method does not guarantee specificity of selectors. Still, it provides a more robust solution compared to the previous code.

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; 
      }
      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 value takes priority. */
}

.node-output02 {
  left: 100%; /* Less significant compared to the earlier rule. */
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Arrangement of elements in MongoDB

In my application, there is a list of games, each with a specific position that determines the order in which they are displayed to users (e.g. 1, 2, 3...). Currently, I am using MongoDB to store all the game data. Let's say I have a game with positi ...

Chosen Dropdown selection - Retrieve/Receive information

One of the challenges I'm facing involves a dropdown list on my web form that contains various dates. My main query is: How can I retrieve data for the selected date from a MySQL database and present it to the user? Additionally, if the chosen date do ...

Analyze a designated section and display the top 3 frequently used words

Below is the code snippet provided: <body> <div id="headbox"> <p>Whatever...</p> </div> <div id="feed"> <div> <p>I hate cats</p> </div> <div> <p>I like ...

AJAX - Alert with a beep sound each time a new entry is inserted into the database table

Having trouble determining the condition to test for when a new record is added to the database table. Can anyone lend a hand? Here's a snippet of the data retrieved from the database: ['Paul Abioro', '<a href="/cdn-cgi/l/email-prot ...

Customizing the appearance of the Bootstrap Typeahead

I've been experimenting with the Bootstrap Typeahead for my search feature. I successfully implemented the dropdown list using Ajax. However, I am looking to customize the width, padding, and background color of the dropdown menu, which is currently w ...

The mystery behind the enigmatic combination of ajax, JQuery,

Seeking Assistance! All fields are displaying undefined values function UpdateData(){ var id = $('#id').attr('value'); var name = $('#name').attr('value'); var department = $('#departament'). ...

How do I avoid this error while using a for loop with Axios and JSON?

Trying to retrieve data from a URL using a for-loop in my code snippet below: axios.get(Url).then((response) => { let getJsonAPI = response.data.data.products; if (response.data.data.products.length > 0) { state.jsonGetProduc ...

What are the steps to create a custom progress bar using JavaScript?

I have experience with HTML and CSS. Below is the HTML code: <div id="wrapper"> <ul id="top"> <center><li><a href="#one" class="button">GENERATE</a></li></center> </ul> <div class="box" i ...

Creating a JavaScript function that increments or decrements a variable based on keyboard input is a useful feature

My goal is to have a count start at 100 and then either count up or down by 1 when a specific keyboard button is pressed. Currently, I am using the keys 8 and 2 on the keypad, which represent ascii numbers 104 and 98. So far, the code I have only allows f ...

Ionic 2's Navigation Feature Failing to Function

I need to implement a "forgot password" feature on my login page. When a user clicks the button, they should be redirected to the "forgot password" page. Below is the code snippet from my login.html <button ion-button block color="blue" (cli ...

Strategies for showcasing a dynamic date selection tool

I am facing an issue with a datepicker input inside a while loop for generating dynamic data. The problem is that the datepicker only seems to work on the first input. How can I rectify this? Here is my blade: <div class="row"> @fo ...

Determining if a user is already logged in from a different device using express-session

After a user logs in, I assign the username to their session with the code: req.session.username = "...."; This identifies the session with a username, but now I need to figure out how to detect if this same username is already logged in from another dev ...

Animating a 3D object's movement using Gsap.js

Recently, I've been experimenting with modules, three.js, and gsap. I'm attempting to animate a 3D object along a path. I found a solution using "common js" that works well here: https://codepen.io/uiunicorn/pen/zYZoYpV However, when I try to in ...

Issues are arising with the for loop in an express node js app using ejs, as it is not displaying the intended data and

I am currently utilizing a for loop in JavaScript to display all the users from the database using ejs. I have included the code snippet below. This is within an express/node js application where SQL is used for data storage. <div class = "Contacts ...

Manipulate the text within a canvas element using JavaScript

In this scenario, suppose json.mes represents the received message from Ajax. There is a button implemented to display the message in a canvas box. Although I have attempted to retrieve the message using getElementById (as shown below), it seems to be in ...

Exploring every conceivable method for accessing a file from a distant server

I am striving to maximize the flexibility of my script, thus I am seeking all potential methods in PHP and JavaScript to access the content (and not the source code) of a PHP file from a remote server. I have come across CURL, fopen, and include for PHP ...

Vue component fails to render on a specific route

I am having trouble rendering the Login component on my Login Route. Here is my Login component code: <template> <v-app> <h1>Login Component</h1> </v-app> </template> <script> export default { } </script ...

In React, what is the correct term for "selection boxes" when choosing multiple items in Finder?

I'm in search of a React component that allows me to select multiple elements on the screen by clicking, holding, and forming a square around them. I've tried searching for terms like 'selection box' and 'React select elements,&apo ...

Navigating forwards in Angular 7 causes loss of state

I have a situation with my angular 7 Ionic application. When I navigate to a page, I use the following code snippet: navigateToDetail(entity: User) { const navigationExtras: NavigationExtras = { state: { entity, entityId: entity.id ...

The personalized confirmation dialog is experiencing malfunctions

I have designed my own custom dialogs using Bootstrap and jQuery, such as Alert and ConfirmDialog. Here is a sample: http://jsfiddle.net/eb71eaya/ The issue I am facing is that in the callback function, I make an AJAX call. If it returns true, I want to ...