Reputation:
I want to select a bunch of span
s in a div
whose CSS contains a particular background color. How do I achieve this?
Upvotes: 30
Views: 38097
Reputation: 47
Are you still tired of writing procedures for selecting something? Here is the general procedure for selecting anything. You don't have to write another procedure for select anywhere. Try it, this is example:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<script>
function ReplaceAll(base,told,tnew) { // replace insensitive
if (told=="") {return base;}
var u=base.toLowerCase();
var t=told.toLowerCase();
var ss=""; var p=-1; var i=0;
p=u.indexOf(t);
if (p>-1) {
let mLen=told.length;
while (p>=0) {
ss+=base.substr(0,p)+tnew;
i=p+mLen;
base=base.substr(i);
u=u.substr(i);
p=u.indexOf(t);
}
ss+=base; //fix bug
return ss;
}
return base;
}
function Len(pS) {return pS.length;}
function Lower(pS) {return pS.toLowerCase();}
function Upper(pS) {return pS.toUpperCase();}
function Trim(pS) {return pS.trim();}
function Sub(pS, p1, p2=0) {
if (p2<=0) {p2=Len(pS);}
if (p1<=0) {p1=0;}
return pS.substring(p1,p2);
}
function IndexAt(base, t ,pos=0) { //index from position
if (pos<0) {pos=0;}
var x=base.substr(pos);
var p=x.indexOf(t);
if (p>=0) { return p+pos;} else {return -1;}
}
function NormStyle(pS) { //normalization style
pS=Trim(pS);
if (Len(pS)==0) {
return pS;
}
if (IndexAt(pS,":")>=0) {pS+=";";} // style+";"
pS=ReplaceAll(pS,';;',';');
pS=ReplaceAll(pS,' ',''); // without spaces! -> font-name
pS=ReplaceAll(pS,',',', ');
//-- color:#* ->color:rgb(*), because jQuery in runtime replace style: color:#* -> rgb(*), font_size:?em -> ?px .. etc.
var p1=0; var p2=0;
var t1=""; var t2="";
p1=IndexAt(pS,"color:#");
while (p1>=0) {
p2=IndexAt(pS,';',p1);
if (p2>0) {
t1=Sub(pS,p1,p2); //color:#ff0000
t2=Sub(t1,6); //#ff0000
t2=RGB(t2);
pS=ReplaceAll(pS,t1,"color:"+t2);
}
p1=IndexAt(pS,"color:#",p0+2);
}
return pS;
}
function RGB(pS) {
var rgb=pS;
if (IndexAt(Trim(rgb),"#")==0) {
rgb=Trim(rgb);
rgb=rgb.padEnd(7,"0"); //#ff00 -> #ff00000
var patt = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/;
var matches = patt.exec(rgb);
rgb = "rgb("+parseInt(matches[1], 16)+", "+parseInt(matches[2], 16)+", " +parseInt(matches[3], 16)+")";
}
return rgb;
}
function NQ(pS) { //NQ("alfa 'b`c' x")=="alfa ♣♣♣♣♦ x"
var bo=false; var mEnd=true;
var typ=0;
var s="";
for (let i=0; i<Len(pS); i++) {
switch (pS.charAt(i)) {
case '"': if (typ==1) {typ=0;} else { if (typ==0) {typ=1;} } break;
case "'": if (typ==2) {typ=0;} else { if (typ==0) {typ=2;} } break;
case "`": if (typ==3) {typ=0;} else { if (typ==0) {typ=3;} } break;
}
if (typ==0) {
if (!mEnd) { mEnd=true; s+="♦"} else {s+=pS.charAt(i);}
} else {
s+="♣"; mEnd=false;
}
}
if (typ>0) {s="Error:♣ Not valid string termination";}
return s;
}
function Element(pSelector, pFilter="",pNumbers="",pTrace=1) { //pTrace: 0=no trace, 1=console.log, 2=alert trace
switch (pTrace) {
case 1: console.log("start trace"); break;
case 2: alert("start trace"); break;
}
//--- pNumbers ---
pNumbers=Trim(pNumbers);
var mNumbers=""
if (pNumbers>"") { mNumbers = "," + pNumbers + ","; }
//--- pFilter validation for eval --- // Assignment(=) is not allowed
pFilter=Trim(pFilter);
if (pFilter>"") {
let s=ReplaceAll(pFilter,"===","♠♠♠");
s=ReplaceAll(s,"==","♠♠");
if (IndexAt(s,"=")>0) {
s=NQ(s);
if (s=="Error:♣ Not valid string termination") {
if (pTrace==1) {console.log(s+" pFilter:"+pFilter);}
alert(s);
return null;
} else {
if (IndexAt(s,"=")>0) {
let x="Error: Assignment is not allowed (=/==)";
if (pTrace==1) {console.log(x+", "+s);}
alert(x+"\n"+s);
return null;
}
}
}
}
var mCnt=0;
var mObj=$(pSelector).filter(function(){
var bo=true;
var s=""; var t=""; var ss="";
mCnt++;
//--- pNumbers --
if (mNumbers>"") {
t=","+mCnt+",";
if (IndexAt(mNumbers,t)<0) {
bo=false;
}
}
//-----RESULT by pNumbers ---
if (pNumbers>"" && pTrace>0) {
if ( !bo || (bo && pFilter=="") ) {
switch (pTrace) {
case 1: console.log(mCnt+". Result by numbers: "+bo+", numbers:["+pNumbers+"]"); break;
case 2: alert(mCnt+". Result by numbers: " +bo+", numbers:["+pNumbers+"]"); break;
}
}
}
//-------- pFilter ----
if (bo && pFilter>"") {
var cPrefix="{:"; var cSufix="}";
var p1=0; var p2=0; var p3=0;
var t1=""; var t2=""; var t3=""; var t4=""
var r1=""; var r2="";
var lenP=Len(cPrefix); var lenS=Len(cSufix);
s=pFilter; ss=s;
p1=IndexAt(s,cPrefix);
while (p1>=0) {
r1=""; p2=IndexAt(s,cSufix,p1);
if (p2>=0) {
t1=Sub(s,p1,p2+1) //{:css.color} //{:html}
t2=Sub(t1,lenP); //css.color} //html}
t2=Sub(t2,0,Len(t2)-lenS); //css.color //html
t2=Lower(t2);
p3=IndexAt(t2,".");
if (p3>0) {
t3=Sub(t2,0,p3); //css
t4=Sub(t2,p3+1); //color
r1='$(this).'+t3+'("'+t4+'")'; //$(this).css("color")
if (t3=='attr' && t4=='style') {
r1='NormStyle(String($(this).attr("style"))';//exception for attr.style, because jQuery in runtime change attr style
}
} else {
r1='$(this).'+t2+'()'; //html -> $(this).html()
if (t2=="data") {r1='JSON.stringify('+r1+')';} //exemption for data -> JSON.stringify( $(this).data() )
}
}
if (t1>"" && r1>"") {s=ReplaceAll(s, t1, r1);}
//--- evaluate only in trace mode for debug ---
if (pTrace>0) {
r2=eval(r1);
ss=ReplaceAll(ss,t1,"'"+r2+"'");
}
//--- next iterate ---
p1=IndexAt(s,cPrefix,p1+2);
}
// --- trace1 ---
if (ss>"" && pTrace>0) {
switch (pTrace) {
case 1: console.log(mCnt+". "+ss); break;
case 2: alert(mCnt+". "+ss); break;
}
}
//--- evaluate ---
bo=eval(s);
// --- trace2 ---
switch (pTrace) {
case 1: console.log(mCnt+". FILTER: "+bo+", [:"+s+"]"); break;
case 2: alert(mCnt+". FILTER: "+bo+"\n ["+s+"]"); break;
}
}
//--- RESULT ---
return bo;
})
switch (pTrace) {
case 1: console.log("end trace"); break;
case 2: alert("end trace"); break;
}
return mObj;
}
$(document).ready(function(){
$("button").click(function(){
var mObj=Element("body p a",
"{:css.color}==RGB('#ff00') && {:css.font-size}=='16px' && 'href='+{:attr.href} > '' ",
"2,3"
);
if (!$.isEmptyObject(mObj)) {mObj.hide();} // or mObj.css('display','none')
/*
// --- hidden element only from selector ":hidden"
mObj=Element('a:hidden');
if (!$.isEmptyObject(mObj)) {mObj.show();}
*/
/*
//css.
{:css.color} -> $(this).css("color")
{:css.font-size} -> $(this).css("font-size")
{:css.display}-> $(this).css("display")
//attr.
{:attr.href} -> $(this).attr("href")+"]"+
* {:attr.style} -> NormStyle(String($(this).attr("style"))
{:attr.id} -> $(this).attr("id")
{attr.class -> $(this).attr("class")
//spec
{:html} -> $(this).html()
{:index} -> $(this).index()
* {:data} -> JSON.stringify($(this).data())
{val} -> $(this).val()) // for value //or prop.value
//prop
{:prop.checked} -> $(this).prop("checked")
{:prop.selected} -> $(this).prop("selected")
{:prop.selectedIndex} -> $(this).prop("selectedIndex")
{:prop.disabled} -> $(this).prop("disabled")
//comment
prop() for:
disabled,checked,selected,value,selectedIndex,tagName,nodeName,nodeType,ownerDocument,defaultChecked
val() for value
*/
});
});
</script>
</head>
<body>
<h2>jQuery.Element() for filtering "any"</h2>
<p>
<a id="1" href="?m=1" style="color:#ff0000;font-size:16px;" class="alpha" data-x="123" data-y="123">1. ALPHA</a>
, <a id="2" style="color:#ff0000;font-size:16px;">2. BETA </a>
, <a id="3" href="?m=3" style="font-size:16px;">3. GAMMA</a>
</p>
<a id="4" href="?m=4" style="font-size:14px;">END</a>
<button>Click me</button>
</body>
</html>
Upvotes: 0
Reputation: 828
// Get all spans
let spans = document.querySelectorAll('div#someDiv span');
// Convert spans nodeslist to array
spans = Array.from( spans );
// Filter spans array
// Get CSS properties object of selected element - [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle)
let arr = spans.filter( span => String( document.defaultView.getComputedStyle( span, null ).backgroundColor ) == 'rgb(0, 0, 0)' );
// Change background color of matched span elements
arr.forEach( span => {
span.style.backgroundColor = 'green';
});
.one, .two {
background-color: black;
}
.three {
background-color: red;
}
<div id="someDiv">
<span class="one">test one</span>
<span class="two">test two</span>
<span class="three">test three</span>
</div>
Upvotes: 2
Reputation: 84493
if i understand the question correctly, the selector [attribute=value]
will not work because <span>
does not contain an attribute "background-color". you can test that out quickly to confirm it won't match anything:
$('#someDiv span[background-color]').size(); // returns 0
given:
.one, .two {
background-color: black;
}
.three {
background-color: red;
}
here's a snippet that will work:
$('div#someDiv span').filter(function() {
var match = 'rgb(0, 0, 0)'; // match background-color: black
/*
true = keep this element in our wrapped set
false = remove this element from our wrapped set
*/
return ( $(this).css('background-color') == match );
}).css('background-color', 'green'); // change background color of all black spans
.one, .two {
background-color: black;
}
.three {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<div id="someDiv">
<span class="one">test one</span>
<span class="two">test two</span>
<span class="three">test three</span>
</div>
Upvotes: 46
Reputation: 5657
Use the attribute selector [attribute=value] to look for a certain attribute value.
#id_of_the_div span[background-color=rgb(255,255,255)]
Upvotes: -8