Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #35149

Re: Altering a CSS class with JavaScript?

From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Newsgroups comp.lang.javascript
Subject Re: Altering a CSS class with JavaScript?
Date 2018-06-01 13:25 +0200
Organization PointedEars Software (PES)
Message-ID <3197134.joGGxDtPI3@PointedEars.de> (permalink)
References <1df34733-dc9a-4edf-a4b8-92dc1de90a16@googlegroups.com> <c4bb0748-cc2e-4634-b263-42b01cb64801@googlegroups.com> <233c3ea9-b903-44ad-8435-2a6236003a38@googlegroups.com>

Show all headers | View raw


Michael Haufe (TNO) wrote:

> Michael Haufe (TNO) wrote:
>> Dr J R Stockton wrote:
>> > I have a long page containing numerous HTML elements
>> > of class ZYZ.
>> > 
>> > On page load complete, class XYZ is {display: block} or
>> > not defined.
>> > 
>> > At a certain moment, I wish class XYZ to be {display: none}.
>> > 
>> > At a later moment, I wish class XYZ to be {display: block}.
>> > 
>> > What JavaScript do I need to alter the value of the display
>> > property of a class?
>> > 
>> > How can JavaScript create the initial XYZ?
>> > 
>> > The page must be redrawn after the change, preferably just one
>> > redraw per change to XYZ.
>> 
>> My first reaction is that you are approaching it in potentially a less
>> than optimal manner.

That was my second reaction.  My first one was “Google is your friend!”.

>> Here is an impressionistic example of my suggestion:
>> 
>> <style>
>>     .xyz {
>>         display: none;
>>         ...
>>     }
>>     .xyz-visible {
>>         display: block;
>>         ...
>>     }
>> </style>
>> 
>> <div class="xyz"> Hello World </div>
>> 
>> <script>
>>     let xyz = document.querySelector('.xyz')

As in this case there are “numerous HTML elements of class ZYZ”, one would 
want to use document.querySelectorAll('.xyz') instead.

There is also a DOM-built-in getElementsByClassName() now which should be 
more efficient to use (as it only needs to consider “class” attribute 
values).

However, ISTM that something like that is precisely what the OP tried to 
avoid out of valid concerns about runtime and memory efficiency.

The good news is that the collections to which references are returned are 
“live” (this is where, I think, all emulations must fall short); so it 
suffices to store the reference so that it is non-locally accessible.
The bad news is that iterating over the items still does not scale well.

However, one must keep in mind that the “class” attribute value can also be 
modified on a common ancestor or sibling instead of all target elements;
in combination with a contextual selector, this avoids the aforementioned 
iteration.

>>     xyz.classList.add('xyz-visible')

… where the usual DOM4/HTML5 caveats apply, of course.

> If you insist on manipulating a css rule directly, it can be done in a bit
> more complicated way:
> 
> <script>
>   function getRuleWithSelector(selector) {
>     return Array.from(document.styleSheets, sheet =>

Although a single parameter identifier is not a syntax error (in Google V8 
JavaScript), for consistency ISTM to be a good idea to always use 
parentheses for the parameter list, respectively.

>       Array.from(sheet.cssRules).find(rule => rule.selectorText ===
>       selector)
>     )[0]
>   }
>   // finding the selector is expensive, so only do it once
>   let xyzRule = getRuleWithSelector(".xyz")
>   xyzRule.style.display = 'block'
> </script>

For more than one-time access, it is more efficient to create and use a 
selector-to-rule map:

As a starting point:

  let selectorToRule = new Map();

  Array.from(document.styleSheets).forEach((sheet) => {
    Array.from(sheet.cssRules || sheet.rules).forEach((rule) => {
      let selectorText = rule.selectorText;
      selectorToRule.set(selectorText,
        selectorToRule.has(selectorText)
          ? selectorToRule.get(selectorText).push(rule)
          : [rule]);
    });
  });

  selectorToRule.get(".xyz")[0].style.display = 'block';

    [Thanks for reminding me of ECMAScript 2015’s Array.from(); so unbounded
     .slice.call() should be a thing of the past now.  JFTR, I added an
     Array.from() that uses Array.prototype.map() to JSX:object.js on
     2013-09-04 :) ]

The most simple, compatible, and arguably most efficient, way to modify a 
stylesheet is to append a new “link” or “style” element to the “head” 
element.  (However, I am not certain if it works with “link” elements, too.)

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Altering a CSS class with JavaScript? Dr J R Stockton <J.R.Stockton@physics.org> - 2018-05-31 14:44 -0700
  Re: Altering a CSS class with JavaScript? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2018-05-31 22:23 -0700
    Re: Altering a CSS class with JavaScript? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2018-05-31 22:28 -0700
      Re: Altering a CSS class with JavaScript? "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2018-06-01 12:38 +0200
        Re: Altering a CSS class with JavaScript? Dr J R Stockton <J.R.Stockton@physics.org> - 2018-06-03 11:17 -0700
          Re: Altering a CSS class with JavaScript? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2018-06-05 10:50 -0700
      Re: Altering a CSS class with JavaScript? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-01 13:25 +0200
        Re: Altering a CSS class with JavaScript? Dr J R Stockton <J.R.Stockton@physics.org> - 2018-06-02 11:06 -0700
          Re: Altering a CSS class with JavaScript? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-02 20:51 +0200
            Re: Altering a CSS class with JavaScript? snipeco.2@gmail.com (Sn!pe) - 2018-06-02 21:19 +0100
        Re: Altering a CSS class with JavaScript? Maik Koenig <usenetspam@maikkoenig.de> - 2018-06-02 22:48 +0200
          Re: Altering a CSS class with JavaScript? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-03 00:25 +0200

csiph-web