Bug: element query style targeting a class is not being removed when class is removed
jorroll opened this issue · comments
Hi there! First off, this is an awesome library and spec! I've checked out a few interpretations of element queries, I like this one by far the best.
Secondly, I think I'm running into a bug in the library.
If I construct an element query like so
@element "#divOne.active" {
h2 { color: red; }
}
The element query's styles are correctly applied when #divOne
gains the .active
class, but when #divOne
loses the .active
class, the element query's styles are not being removed.
You can check out a plunkr here: http://plnkr.co/edit/7wbL5WxOA9wHoQWJsCA1?p=preview
Hi @thefliik :D Thanks for the input!
The reason this is happening is because the moment #divOne.active
becomes valid, the EQCSS plugin is marking it with an attribute. There are two workarounds for what you're trying to do with the way EQCSS works as a plugin right now:
- write the query for
#divOne
and have the selector resolve the.active
class - use
EQCSS.reset
andEQCSS.load
after each toggle to reset the attributes
I think the first one will work better for performance, consider my (simplified) demos here and imagine it's your demo code:
<h2>This should be red when #divOne has .active</h2>
<input type=button onclick="divOne.className = divOne.className=='active'?'':'active'" value=Toggle>
<div id=divOne>This is divOne</div>
<style>
@element #divOne {
eval('(className.indexOf("active") !== -1) && "h2"') {
color: red;
}
}
</style>
<script src=http://elementqueries.com/EQCSS.js></script>
Here we have the @element
query written for the #divOne
ID so this applies all the time. Every time EQCSS is recalculated it will resolve the eval()
, which in this case is outputting a selector of h2
or `` (nothing). If any elements matching #divOne
have a className that includes the text `active`, this rule will output with a selector text of `h2`, otherwise it's just output as `{ color: red; }` with no selector and discarded by the browser (applying to nothing).
The second alternative is less ideal, but seems to be set up more like your demo. If you're desiring to use #divOne.active
as the element query, you'll need to run EQCSS.reset()
, your class-toggling code, then EQCSS.load()
to reload EQCSS. This will likely be slow, and the reset function isn't perfect - so I would recommend not doing this - but I'll include it for completeness so you understand how to work around it :D
<h2>This should be red when #divOne has .active</h2>
<style>
@element #divOne.active {
h2 {
color: red;
}
}
</style>
<input type=button onclick="EQCSS.reset();divOne.className = divOne.className=='active'?'':'active';EQCSS.load()" value=Toggle>
<div id=divOne>This is divOne</div>
<script src=http://elementqueries.com/EQCSS.js></script>
Here we have a similar setup with HTML, but the rule is written for #divOne.active
. Every time the toggle button is clicked it's resetting EQCSS and reloading it, ensuring that the faulty rule is removed each time.
Hopefully that helps you figure out how to use it in your demo!
@tomhodgins thanks for the explanation! I don't think I ever would have figured that out on my own. I tried both of your methods and they both work. You were also right about the first method being significantly more performant.