Is it somehow possible to parameterize the jQuery addClass() method?
Like, having a css class with a color property which is set when the addClass() method is called?
I hope that makes sense as I am very new to JavaScript and CSS. If it's of importance, I'm working on extending the MediaWiki VisualEditor. There this method is used to immediatly show/render changes made in the editor. But I couldn't find an example which would require parameterization.
If it's not possible, I'd love to know how to do it.
If it's not, maybe someone can suggest how to realize what I want another way?
Edit:
That's the current state:
When I add some annotation to the text, let's say a languageAnnotation, this is called:
this.$element
.addClass( 've-ce-languageAnnotation' )
.addClass( 've-ce-bidi-isolate' )
.prop( {
lang: this.model.getAttribute( 'lang' ),
dir: this.model.getAttribute( 'dir' ),
title: this.constructor.static.getDescription( this.model )
} );
This is ve-ce-languageAnnotation:
.ve-ce-languageAnnotation {
border-bottom: 1px dashed #ccc;
background-color: #ebf3f5;
}
This is ve-ce-bidi-isolate:
.ve-ce-bidi-isolate {
unicode-bidi: isolate;
unicode-bidi: -moz-isolate;
unicode-bidi: -webkit-isolate;
}
I interpreted this as the prop() function setting some kind of parameter. So this is what I tried for my textColor annotation:
this.$element
.addClass( 've-ce-textColorAnnotation' )
.prop( {
color: this.model.getAttribute( 'style' ),
title: this.constructor.static.getDescription( this.model )
} )
;
With ve-ce-TextColorAnnotation:
.ve-ce-textColorAnnotation {
color: red;
}
This always produces red. When I try to enter something else then a legit color, nothing happens.
Edit2: I guess one option would be to create a class for each possible color, and adding the right class depending on the parameter? Like this:
var color = this.model.getAttribute('style');
if (color == 'blue') {
this.$element.addClass( 'blueText' )
} else if (...
but that doesn't look like a really good idea.
Edit 3: According to the top answer in this question, what I want is not possible - but I can directly apply an attribute without using classes by using this.$element.css('attr', 'value'). I guess I can use this for what I need.
It appears you simply want to set a color, rather than add a class. Classes in HTML can be used for stylization or DOM navigation, however in your case you simply want to apply a different color to an element. You don't need to use classes for that, especially if the colors are dynamic.
What you want to do is call jquery's .css() method. It can be used with a single argument like so:
element.css({
'color': 'black',
'height': '100px'
});
or several, if you only want to edit a single property:
element.css('color', 'black');
Without using jQuery, you could also do this:
element.style.color = 'black';
What can you do in a simple way. Let's say you have a drop down from which you chose the colors. On the value attribute of the option you have blueText for blue, redText for red and so on for each color you want.
Then on the code you can get the value. You can see here how to get the value then you have the classes in CSS like redText, blueText and so on.
When the user clicks on the option you catch the event and do this simple pice of code:
this.$element.addClass( 'text that you got from value attribute' )
You can of course remove the classes before you do the add.
Related
I'm trying to make my input field have a black background and white text, but I can't find any documentation for the possible values input.style() can take. I'm currently trying:
input.style('background-color', "#121212", 'color', "#EEE")
The background color works, but the text color doesn't. I followed the same syntax the reference uses so I'm not sure why.
Also if anyone could point me to where in the documentation it lists all the possible arguments for .style() it'd be much appreciated.
The p5 style() function takes only two arguments: the property name and the value. You are trying to set additional properties by adding more arguments, which you cannot do. You need to break this up into two lines and set each property individually.
input.style('background-color', "#121212")
input.style('color', "#EEE")
Try using two separate calls to .style, one for each property you want to set:
function setup() {
noCanvas();
const inp = createElement("input");
inp.value("hello world");
inp.style("background", "yellow");
inp.style("color", "green");
// or chained:
inp
.style("background", "yellow")
.style("color", "green");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
I prefer to style with classes and a CSS stylesheet, separating presentation and behavior and making it easier to apply the style to many elements without writing a ton of repetitive JS:
function setup() {
noCanvas();
const inp = createElement("input");
inp.class("ugly");
inp.value("hello world");
}
.ugly {
background-color: yellow;
color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
Note also, with respect to naming an input input:
p5.js says: you have used a p5.js reserved function "input" make sure you change the function name to something else.
I ask participants yes/no questions in an experiment and they answer by keypress (Y/N). Now, I want to display YES green and NO red.
I'm doing this with Ibex farms where you have an experiment file in .js format. In this file, one defines the "Question controller" as follows:
"Question", {
as: [["Y","Yes"],["N","No"]], //defines keys+answer displays
}
Adding html tags <font-size>, <div style> in this line did not work.
Besides that, there is a .css file in which I can change the color for both answers, but give the same color to both:
span.Question-fake-link {
color: #ff6600; //changing this to red; both Yes and No are red now
cursor: pointer;
}
The third file is a Question.js file which defines behavior and properties of the question controller beyond its appearance. It is too long to post here, I think, and I don't have authorship. But in there, the answers are defined as "left Comment" and "right Comment". So I attempted to add the 4th line at the (I hope) relevant place:
var lcd = $(document.createElement("li"))
.addClass(this.cssPrefix + "scale-comment-box")
.append(this.leftComment);
.document.getElementById("leftComment").style.color = "red"; //added this, made experiment dysfunctional
this.xl.append(lcd);
Does anyone know how to change the colours individually?
I'm sorry, I know this must look complicated, but maybe someone can give me a pointer on what to do...If you need more of the scripts, please let me know.
Many thanks.
EDIT: After trying out some of the suggestions here, I see the answers are somehow as "span.fake-link". Maybe this code snippet can help (line 1/2):
var a = $(document.createElement("span")).addClass(this.cssPrefix + "fake-link");
__Question_answers__[i] = ans;
__Question_callback__ = function (i) {
var answerTime = new Date().getTime();
var ans = __Question_answers__[i];
var correct = "NULL";
if (! (t.hasCorrect === false)) {...}
}
But how can I replace "span" or "fake-link"? I guess I have to replace both. Removing the span.fake-link properties in css-files doesn't seem to help.
EDIT: Or could this be the problem?
if ((this.presentAsScale || this.presentHorizontally) && this.leftComment) {
var lcd = $(document.createElement("li"))
.addClass(this.cssPrefix + "scale-comment-box")
.append(this.leftComment)
.appendTo(this.xl)
this.xl.append(lcd);
}
I attempted to replace "scale-comment-box" by "red" (defined as a class in css before), but that also doesn't help.
You could probably use jquerys css function:
$("<li>")
.addClass(this.cssPrefix + "scale-comment-box")
.css({color:"red"})
.append(this.leftComment)
.appendTo(this.xl);
Since you're already using Javascript, is it feasible for you to add two extra css classes?
One could be .red and the other, .green and then append those classes to the element accordingly at creation:
//CSS
.red{
color:#F00;
}
.green{
color:#0F0;
}
//javascript
//Your javascript seems to be a mix of jQuery and JS so I assume jQuery is imported. If this is incorrect, you would need to use a raw javascript solution
//Hint: Look at document.getElementsByClassName and .classname += "red"
//jQuery version:
$("li").addClass("red") //for any items that need to be red. replace red with green for the green items
I've got a jQuery function that usually works on a Volusion page and for some reason now it's not working. The location.pathname.indexOf targets all pages that have that URL (the site uses GET variables to do searches on the SearchResults.asp page). I've changed the quotations from singles to doubles and I can't seem to figure out anything else to do test it. Does anyone see any syntax errors in this code? There shouldn't be any conflicts since it's only running jQuery (and nothing else like MooTools). I tried to also do an alert of 'Test' after document.ready but nothing happened on the screen. Thanks!
<script>
$(document).ready(function() {
if (location.pathname.indexOf('/SearchResults.asp') != -1 ) {
$('div#content_area').css({'display','none !important'});
}
});
</script>
You have a syntax error.
This:
$('div#content_area').css({'display', 'none !important'});
Should be this:
$('div#content_area').css({'display': 'none !important'});
// ^
// |
// | look here
When using .css() you can use 2 variations.
You can either use it to update a single property which uses the , to separate the name of the CSS property and the value, similar to this:
$('div#content_area').css('display', 'none !important');
Or you can use the new variation, added in jQuery 1.9 which allows you specify multiple styles at once allowing you to specify property-value pairs, similar to this:
$('div#content_area').css({
'display': 'none !important',
'border' : 'solid 1px red'
});
css() and !important
There seems to be an issue when trying to apply a style using .css() and !important.
there is a bug which was raised a long time ago: The Ticket #2066 which was closed and an alternative was shown in that ticked.
It mentions that as an alternative you can set the cssText similar to this when using the multi-style variation:
$('div#content_area').css({
'cssText': 'display: none !important'
});
or this when using the single style variation:
$('div#content_area').css('cssText', 'display: none !important');
Though, as the ticked mentions, a word of caution:
You have to be careful setting cssText since it sets/clears everything
in the css for that element.
Another alternative, which most likely is the safest given the side-effects of cssText, is to create a separate CSS class and apply that, similar to this:
.alwaysHide{
display: none !important;
}
$('div#content_area').addClass('alwaysHide');
Hope this helps.
You are trying to use 2 syntax styles.
Either, you need to do this:
<script>
$(document).ready(function() {
if (location.pathname.indexOf('/SearchResults.asp') != -1 ) {
$('div#content_area').css('display','none !important');
}
});
</script>
or you need to use this:
<script>
$(document).ready(function() {
if (location.pathname.indexOf('/SearchResults.asp') != -1 ) {
$('div#content_area').css({'display' : 'none !important'});
}
});
</script>
I'd like to:
Find a style attribute for all elements in the page (for instance: all elements that have color:#333;)
Change this attribute for all of them (for instance from color:#333 to color:#444).
Do you have any suggestion on doing so?
My suggestion is avoid doing this if at all remotely possible. Instead, use a class to assign the color value, and then you can look up the elements using the class, rather than the color value.
As far as I'm aware, there's no selector (not even in CSS3) that you can use to query a specific style value, which means looping through all elements (or it looks like you can restrict it to all elements with a style attribute) and looking at the element.style.color property. Now, the thing is, even though you write color: #333; in your style attribute, different browsers will echo it back to you in different ways. It might be #333, it might be #333333, it might be rgb(51, 51, 51), it might even be rgba(51, 51, 51, 0).
So on the whole, a very awkward exercise indeed.
Since you've said this is for a Chrome extension, you probably don't have to worry as much about multiple formats, although I'd throw in the ones that we've seen in the wild in case Chrome changes the format (perhaps to be consistent with some other browser, which has been known to happen).
But for instance:
(function() {
// Get all elements that have a style attribute
var elms = document.querySelectorAll("*[style]");
// Loop through them
Array.prototype.forEach.call(elms, function(elm) {
// Get the color value
var clr = elm.style.color || "";
// Remove all whitespace, make it all lower case
clr = clr.replace(/\s/g, "").toLowerCase();
// Switch on the possible values we know of
switch (clr) {
case "#333":
case "#333333":
case "rgb(51,51,51)": // <=== This is the one Chrome seems to use
case "rgba(51,51,51,0)":
elm.style.color = "#444";
break;
}
});
})();
Live example using red for clarity | source - Note that the example relies on ES5 features and querySelectorAll, but as this is Chrome, I know they're there.
Note that the above assumes inline style, because you talked about the style attribute. If you mean computed style, then there's nothing for it but to loop through all elements on the page calling getComputedStyle. Other than that, the above applies.
Final note: If you really meant a style attribute with precisely the value color: #333 and not the value color:#333 or color:#333333; or color: #333; font-weight: bold or any other string, your querySelectorAll could handle that: querySelectorAll('*[style="color: #333"]'). But it would be very fragile.
From your comment below, it sounds like you're having to go through every element. If so, I wouldn't use querySelectorAll at all, I'd use recursive descent:
function walk(elm) {
var node;
// ...handle this element's `style` or `getComputedStyle`...
// Handle child elements
for (node = elm.firstChild; node; node = node.nextSibling) {
if (node.nodeType === 1) { // 1 == Element
walk(node);
}
}
}
// Kick it off starting with the `body` element
walk(document.body);
That way you don't build up large, unnecessary temporary structures. This is probably the most efficient way to walk the entire DOM of a document.
It's definitely more simple if you use jquery.
In any case, the best would be to use classes and use the filter jquery method to get the objects you want.
But if you really want to get them you can do something like:
$(function () {
$('p').filter(function () {
return $(this).css('color') == '#333';
}).css('color', '#444');
});
The above script get the elements with the desired css attribute and set a new css attribute (color #444).
You can't, if you don't add at least a specific CSS class to all this elements you want to track.
Or better, you can with very poor performances by looping on all the elements of the DOM until you find what you're looking for. But please, don't think of doing this
It's as already said really hard / inefficient to query all elements by color.
// refrence: http://stackoverflow.com/questions/5999209/jquery-how-to-get-the-background-color-code-of-an-element
var arr = [];
$('*').each(function (i, ele) {
// is red => save
if($(ele).css('backgroundColor') == ('rgb(0, 0, 255)')) arr.push(ele);
});
console.log(arr);
Here is an JSFiddle Example for it: http://jsfiddle.net/ddAg7/
My recommendation for this is: Don't do it!
Something like
$('selector').each(function() {
if($(this).attr('style').indexOf('font-weight') > -1) {
alert('got my attribute');
}
});
in the if statement you could replace it with a different css... Not sure.. haven't tried on all browsers though :)
oneliner
[...document.querySelectorAll("[style*='color:#333']")].forEach(e=>e.style.color='#444')
function switchColors() {
[...document.querySelectorAll("div[style*='color:#333']")]
.forEach(el => el.style.color = '#f00')
}
<div>EXAMPLE:
<div>
<div style="background: #eee; color:#333;">aaa</div>
<div style="background: gray; color:#00f;">
bbb
<div style="color:#333;">ccc</div>
</div>
</div>
<div style="color:#040;">ddd</div>
<div style="color:#333; font-size: 20px">eee</div>
</div>
<button onclick="switchColors()">Switch Colors</button>
Is it possible to do an if statement in javascript/jquery to determine:
If the value of a certain element's css attribute is equal to a given value?
such as:
if( $('.box').css(background-color = blue) ){
// do this...
}
The css JQuery method, when given only one parameter, will return the value for the given paramenter. You can try this:
var color = $('.box').css('background-color');
if (color == 'rgb(0, 0, 255)' || color == 'blue') // =='blue' <- IE hack
alert("it's blue!\nColor detected: " + color);
The above sample will only work for the first element in the JQuery selector, therefore you should use the .each JQuery method to iterate through the whole selector if you have more than one element in it.
Please note that the .css JQuery method returns a RGB combination in most browsers (except IE), so testing it against a string such as blue will not suffice for non-IE browsers. You can test that in the JQuery API site and my fiddle.
And here's with the proper .each iteration:
$('.box').each(function(i){
var color = $(this).css('background-color');
if (color == 'rgb(0, 0, 255)' || color == 'blue') // =='blue' <- IE hack
alert("div " + i + " is blue!\nColor detected: " + color);
});
JSFiddle
Edit: over a year and half later, I feel like this answer deserves an update.
For most use cases, I'd recommend using a CSS class:
.blue {
color: blue;
}
This allows the usage of the addClass(), removeClass(), toggleClass() methods for manipulation, as well as hasClass() for checking:
if ( $('#myElem').hasClass('blue') ) {
//it has the .blue class!
}
This works seamlessly in all browsers without needing hacks, and as a plus you get better separation of concerns -- that is, if your styling ever changes, say .blue { color: lightblue; }, the JS will keep working without modifications.
Note: of course, this approach is not suitable for a couple rare use cases where the color value is dynamically generated (e.g. using Math.random() or picking a color value off a canvas pixel), in these rare use cases you can still use the first solution in this answer.
You should be able to do something like this:
if ($('.box').css('background-color') === 'blue')
{// do this...}
check for spaces in
if($(this).css('color') == 'rgb(251, 176, 64)')
"SPACE AFTER COMA"
boxes = $('.box');
for(var i = 0;i<boxes.length;i++) {
if(boxes[i].style.backgroundColor =="blue") {
//do stuff
}
}
None of the above seems to work here in 2015. Testing a link's color against the :visited color seems to be true in all cases in Chrome for me. Also if you are not 'sniffing' and genuinely want to know if a link has been clicked during their visit to YOUR website I've found that a simple:
$("a").addClass('visited');
and checking for the class works just fine.
if ( $("a").hasClass('visited'); ){ console.log('do something honorable'); }