While attempting to dynamically add styles to a stylesheet using JavaScript, an error message was encountered stating "Cannot read property 'length' of undefined"

I am currently developing a custom polyfill that enables older browsers like Internet Explorer to interpret and run media queries using traditional CSS selectors. The process is outlined as follows:

  1. Iterate through each stylesheet found in the document
  2. Analyze each style rule within the stylesheet to identify media queries
  3. Determine the targeted device size and apply the appropriate "id" accordingly
  4. Add a CSS line dynamically with the selector to the existing stylesheet

The concept behind the polyfill is to search for media queries, assign a parent "id" to the body based on the device size, such as:

#tablet .wrap { ... }
#mobile .wrap { ... }
#desktop .wrap { ... }

Here is a snippet of the current JavaScript code:

var styleSheets = document.styleSheets;
// Remaining JavaScript code...

Everything is functioning correctly as intended, including adding the CSS rule to the stylesheet. However, I encounter an error at a certain point:

Uncaught TypeError: Cannot read property 'length' of undefined 

The error occurs when calling this function:

addCSSRule( styleSheets[i], '#'+ className +' '+ ruleParts[0], rules[0], 1 );

I need to investigate why the aforementioned error is happening during the function call and when trying to read .length.

My HTML structure resembles the following layout:

<!DOCTYPE html>
<head>
<title>Style Manipulation VIA Javascript</title>

<link rel="stylesheet" href="css/test.css" />
<link rel="stylesheet" href="css/typo.css" />

</head>
<body>

<div class="wrap">
    <p>Lorem ipsum dolor sit amet... </p>
    <p>Lorem ipsum dolor sit amet... </p>
</div>

In conclusion, I must uncover the cause of the inability to read the property length and resolve any issues within the addCSSRule function causing the error.

Answer №1

Exploring the differences between IE and W3C implementations of the styleSheets object reveals interesting insights:

function getStyleRules() {
    var rule, rules;
    var sheet, sheets = document.styleSheets;
    var ruleCssText = ['Rules:','',]

    for (var i=0, iLen=sheets.length; i<iLen; i++) {
      sheet = sheets[i];

      // Retrieve rules using:
      //
      //        W3C model        IE model
      rules = sheet.cssRules || sheet.rules;

      for (var j=0, jLen=rules.length; j<jLen; j++) {
        rule = rules[j];

        // Both models provide access to selector information,
        // but there are case differences in IE so it's advisable to convert to lowercase
        alert('Selector: ' + rule.selectorText.toLowerCase());

        // Extracting rule text
        // W3C model - includes selector and rule
        if (rule.cssText) {
          ruleCssText.push(rule.cssText);

        // IE model - only contains rule without selector
        } else if (rule.style) {
          ruleCssText.push(rule.style.cssText.toLowerCase());
        }
      }
      alert(ruleCssText.join('\n'));
    }
}

Much documentation exists on MSDN regarding the IE model, although it may primarily focus on newer versions rather than older editions that possibly accommodate both models: styleSheet object, rule object

Additional resources include Opera's documentation: Dynamic style - manipulating CSS with JavaScript

Further useful information can be found at: The styleSheet object, The CSS Rule object.

When utilizing web resources, exercise caution, seek alternative references, and extensively test your code across various browsers, especially older ones.

Upon running the code:

> TypeError: styleSheets[i].rules is undefined
> 
> for( a = 0; a < styleSheets[i].rules.length; a++ ) {

The issue arises from mixing the IE (rules) and W3C (cssRules) models, hence it's more efficient to fetch the rules object once: -

  var sheetRules = styleSheets[i].rules || styleSheets[i].cssRules;
  for( a = 0; a < sheetRules.length; a++ ) {

Subsequently:

  if ( sheetRules[a].type == 4 ) {

Note that the IE model lacks a type property within the rules object (despite what MSDN implies), as this feature aligns with the W3C model implemented by IE 9 onwards.

Following that:

>     mediaPart = sheetRules[a].media[0].split(' and ');

Typically, media pertains to the sheet rather than individual rules, thus:

      // Possibly referring to multiple media parts?
      mediaPart = styleSheets[i].media;

Moreover, the IE model presents an empty string under its media property, though you can retrieve its content through:

styleSheets[0].cssText.replace(/\s+/g,' ').match(/@media.+}[^{]+}/)

.

>     // TypeError: mediaPart[1] is undefined
>     dimB = parseInt( mediaPart[1].replace(/[():A-Za-z$-]/g, "") );

This section seems to assume "and" exists within the rule. While specifics aren't provided, if your rules resemble:

@media screen, print { ... }

then media represents a list of media rules where media[0] corresponds to screen and media[1] correlates to print, necessitating iteration over these media rules.

These insights should suffice for now.

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

Encountering a GET-error while trying to nest jQuery/json calls: Resolution Update

My goal is to utilize services for ip-lookup and geo-lookup to pinpoint a visitor's location on a map. This information will be stored in a database and used to display live user locations on a dashboard. Currently, I am working on a script that, whe ...

Send nodejs express static request over to secure https server

Is there a way to ensure all HTTP requests, including those for static files, are redirected to HTTPS? This is the code I currently have: app.use(express.static(__dirname + '/public')); app.get('*', function(req, res) { if (!req. ...

Issue with React.useEffect not functioning in Express application

I'm having trouble with the state not updating or re-rendering in my code. I've tried logging from inside the useEffect function but nothing seems to happen. Any suggestions on how to make the useEffect work properly? app.js var createError = re ...

Dragging objects on a map is done using jQuery and it causes them to bounce

Currently, I am working on implementing the JQuery Draggable feature. My idea is to create a map where I can attach image Divs to it dynamically using Jquery. So far, I have been successful in adding the Divs and making them draggable around the map effici ...

Utilizing Three JS to add Gradient to external Models

When it comes to comparing the gradient colors applied to two spheres, the key lies in one statement: sphereGeometry = sphereGeometry.toNonIndexed(); https://i.sstatic.net/pBBs9.jpg https://i.sstatic.net/KRULV.jpg I prefer the smoother look achieved by ...

Encountering a 'JSON parsing error' while transmitting data from Ajax to Django REST Framework

I've been encountering an issue while trying to send a JSON to my REST API built with Django Rest Framework. Every time I make this request, I receive an error message, regardless of the view I'm accessing. I suspect the problem lies in the AJAX ...

Is it advisable to use npm devDependencies in a production environment?

While reviewing the package.json file for one of our products at work, I noticed that the SDK uses socket.io for a crucial function even though socket.io-client is listed as a devDependency. Despite this discrepancy, the SDK works flawlessly for our clie ...

Tips for Avoiding Inheritance of a Specific Method

Let's say we have two classes, A and B. Class B extends class A, inheriting all of its methods. It is also possible to override these inherited methods. The question at hand is whether it is possible to prevent class B from inheriting a specific metho ...

An error was encountered: Component.setState is undefined and cannot be read, leading to a TypeError

Could the error be caused by the fact that the Counter component remains at a count of 0, with this not bound anywhere? class Counter extends React.Component { constructor(props) { super(props) this.state = { count: 0 ...

What is the reason behind changing the line-height for one inline-block sibling div affecting both divs?

Here's my setup: <div> <div style="display:inline-block; ">div_1</div> <div style="display:inline-block; line-height:20px;">div_2</div> </div> Why does setting the line-height property f ...

Inside nested ng-transclude, the AngularJS directive isolates the scope

I've been scouring the internet for a solution to my problem, but I still haven't found it. In my application, I have a directive that enables users to sort and search through various lists of items. These items can vary in type and usage, leadi ...

When I test my jQuery scripts in jsfiddle, they run smoothly. However, they do not seem to work properly when I

My code is almost perfect, but the jQuery function is giving me trouble. It works fine in jsfiddle, but for some reason, it's not functioning in my HTML file. I don't believe extra characters are being added when copying from the HTML file. I hav ...

NodeJs Classes TypeError: Unable to access 'name' property as it is undefined

I am currently developing a useful API using Node.js. In order to organize my code effectively, I have created a UserController class where I plan to include all the necessary methods. One thing I am struggling with is how to utilize a variable that I set ...

Animate div visibility with CSS transitions and Javascript

I'm currently working on incorporating an animation into a div that I am toggling between showing and hiding with a button click. While I have the desired animation, I am unsure of how to trigger it using JavaScript when the button is clicked. Can any ...

JSON parsing successfully but failing to deliver expected results

Currently tackling my web design assignment that involves working with AJAX. I'm encountering an issue with the JSON.parse() function. The problem arises when I execute a GET request on my JSON database using AJAX: artist_list = $.ajax({ dataType ...

Rendering a page for a missing resource

Within the App.js file, the routes component is currently only wrapping a portion of the website. However, I would like the NotFound component to be rendered for the entire page if an incorrect URL is entered. Can you please provide guidance on how this ...

Adjust the values of a specific field in every document by referencing another field within the same document

Within my database, I store student records that each contain the fields amountOwed and tuition. The task at hand is to update the value of amountOwed to be the sum of its current value and tuition. I am considering utilizing a .find query to retrieve al ...

The error message "element.getAttribute is not defined" is common when using the Perfect

I'm facing an issue while trying to implement the perfect-scrollbar plugin on my AngularJS website. The error I encounter is as follows: TypeError: element.getAttribute is not a function at getId (http://localhost/Myproject/js/lib/perfect-scrollb ...

Angular/Karma Unit Test for HttpClient

During my research on unit testing, I came across some very useful examples. Most of the examples focus on unit testing functions that interact with Angular's HttpClient, and they usually look like this: it('should return an Observable<User[] ...

Using pre-set values for filters in a mongo selector: best practices

I am currently working on implementing filters for a mongo find query. The objective is to have the mongo selector limit the retrieved data based on the specified filters. However, if no filter is provided (the filter has a null or default value), then the ...