addClass(); jQuery Function Not Working in Firefox - javascript

I have a script that picks a random background image for the body element of my document from a directory called bg-images. If the chosen background image has "_dark" in the image file name, I would like to add a special class to the body element.
Here is the jQuery I'm using. It works great in Chrome & Safari, but does nothing in Firefox:
var backgroundImage = $('body').css('background');
var isitdark = "_dark";
if (backgroundImage.indexOf( isitdark ) != -1 ) {
$('body').addClass("dark");
} else {
$('body').removeClass("dark");
}
How come this doesn't do anything in Firefox? Is there a better way of writing it?
I've tried adding "type=text/javascript" to all my script tags but that doesn't seem to help and the rest of the jQuery on my site works correctly in all browsers.

You're not getting the background image with $('body').css('background'); Use .css('background-image')
var backgroundImage = $('body').css('background-image');
It's not necessary because the string _dark will or will not be there but if you want to you can remove the url() or url("")
var backgroundImage = /url\(\s*(['"]?)(.*?)\1\s*\)/g.exec($('body').css('background-image'))[2];
Works fine in FF
http://jsfiddle.net/mNX3A/

background is a shorthand property. Shorthand properties are not guaranteed to be retrieved correctly with css:
Retrieval of shorthand CSS properties (e.g., margin, background, border), although functional with some browsers, is not guaranteed.
If you specifically want to get background-image, get background-image:
var backgroundImage = $('body').css('background-image');

Related

Chrome not handling .style = "background-color:#333223;"

In the code included below, the script is toggling a div on and off. The .style
code, controls the background color of the the parent element of the div being toggled
on and off. The code works in Opera but not in Chrome, and I haven't been able to
research (search) a solution.
I can of course move on and write other code and achieve what I need, but this has my
curiosity up now.
function CheckOutOpn(){
var Inny = document.getElementById("RightPaneASxOrderForm");
MVxCheckOutForm();
CDxButtonOpnChkOut();
MVxCLOSExBttnChkout();
Inny.style = "background-color:#332223;";
}
function CLOSExCheckOut(){
var Inny = document.getElementById("RightPaneASxOrderForm");
MVxButtonOpnChkOut();
CDxCLOSExBttnChkout();
CDxOrderFormItself();
Inny.style = "background-color:#33B32E;";
}
I think you should be using:
Inny.style.backgroundColor = "#332223";
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.style
... Except in Opera, styles can not be set by assigning a string to the
(read only) style property, as in elt.style = "color: blue;". This is
because the style attribute returns a CSSStyleDeclaration object.
If you want to set the style of an element textually, you need to use either
Inny.style.cssText="background-color:#33B32E"
or
Inny.setAttribute("style","background-color:#33B32E")
or you can set the properties directly:
Inny.style.backgroundColor = "#33B32E";
I think this will work for you fine. only mistake you are doing is, when you are adding the css properties to the element.
function CheckOutOpn(){
var Inny = document.getElementById("RightPaneASxOrderForm");
MVxCheckOutForm();
CDxButtonOpnChkOut();
MVxCLOSExBttnChkout();
Inny.style.backgroundColor = "#332223";
}

CSS by data-attribute will not refresh/repaint

In a HTML5/JS application we have a view with some styles depending on the data-attribute of elements:
like
<li data-level="0"></li>
or
<li data-level="1"></li>
CSS
li[data-level^="1"] {
/* some styles */
}
This seems to work just fine everywhere on page reload.
But when the data-attribute get set programmatically via JS, the CSS properties get rendered in all relevant desktop browsers, but not in mobile safari.
JS part looks like this:
this.$el.attr('data-level', this.model.getLevel())
Any ideas on how to force to apply those properties (refresh/repaint something) ?
I would like to avoid using the class attribute and different classes as things are more complex than shown here...
ok, changing data attributes simply doesn't seem to trigger a redraw of the element in all browsers !?
Changing the class attribute however does.
Kind of a workaround, but does the trick.
this.$el
.attr('data-level', this.model.getLevel())
.addClass('force-repaint')
.removeClass('force-repaint');
As seen here: Changing a data attribute in Safari, but the screen does not redraw to new CSS style
In my case, I was working with a font icon generated with icomoon and using the data attribute data-icon to change the HTML entity dynamically.
On page reload, it would work in tandem with this css:
[data-icon]:before {
content: attr(data-icon);
}
But without reload, and even by changing classes, it didn't change, just displayed the code.
<span class="font-icon" data-icon=""></span>
What worked for me was using this function, which I edited to the following (assuming code in the shape of e901):
export class StringUtils {
static emptyElement = document.createElement('div');
static fontCodeToSymbol(code: string): string {
let element = StringUtils.emptyElement;
let symbol: string | nullable = `&#x${code};`;
if (symbol && typeof symbol === 'string') {
element.innerHTML = symbol;
symbol = element.textContent;
element.textContent = '';
}
return symbol || '';
}
}
Which would directly feed the correct character in data-icon:
<span class="font-icon" data-icon=""></span>

Jquery change background size AND image src

I'm trying to change both background-image and background-size (so it fits the div)
$(".clickableimg").click(function() {
var choosenpic = $(this).attr('id');
$("#image").val(choosenpic);
$("#preview").css("background","url(backgrounds/"+choosenpic+")");
$("#preview").css("background","size('50%')");
});
Do you know how I can change more css attributes?
Setting the background style twice overwrites it, so only the last one will stick, you'll need to use valid CSS properties, like background-image and background-size to change them seperately :
$(".clickableimg").on('click', function() {
var choosenpic = this.id;
$("#image").val(choosenpic);
$("#preview").css({
'background-image' : 'url(backgrounds/'+choosenpic+')',
'background-size' : '50%'
});
});
I'm not entirely sure that your code works correctly because I think you mean
$("#preview").css("background-image","url(backgrounds/"+choosenpic+")");
but if what you have works already then cheers.
You can change any css attributes as long as its supported by the browser.
$("#preview").css("display", "none")
$("#preview").css("width", "5000px")
$("#preview").css("text-shadow", "...")
$("#preview").css("box-shadow", "...")
$("#preview").css("border", "...") ..
I can go on and on..but here is a list of some of CSS3 properties you can play with
http://www.quackit.com/css/css3/properties/
First of all if you're new to javascript you should first look at how javascript basically works before starting with a framework like jQuery. According to your question the following jquery plugin should help you to accomplish your task:
https://github.com/louisremi/background-size-polyfill
This plugin will help you get it working in IE8 too.

How to dynamically set and modify CSS in JavaScript?

I have some JavaScript code that creates some div elements and it sets their CSS properties.
Because I would like to decouple CSS logic from my JavaScript code and because CSS is easier to read in its own .css file, I would like to set the CSS className of my element and then dynamically inject some values into the defined CSS property.
Here is what I would like to do :
style.css:
.myClass {
width: $insertedFromJS
}
script.js:
var myElement = document.createElement("div");
myElement.className = "myClass";
I want to do something like this but at that point myElement.style.width is empty
myElement.style.width.replaceAll("$insertedFromJS", "400px");
I think my problem here is that after the call to myElement.className = "myClass", the CSS is not yet applied.
If I understand your question properly, it sounds like you're trying to set placeholder text in your css file, and then use javascript to parse out the text with the css value you want to set for that class. You can't do that in the way you're trying to do it. In order to do that, you'd have to grab the content of the CSS file out of the dom, manipulate the text, and then save it back to the DOM. But that's a really overly-complicated way to go about doing something that...
myElement.style.width = "400px";
...can do for you in a couple of seconds. I know it doesn't really address the issue of decoupling css from js, but there's not really a whole lot you can do about that. You're trying to set css dynamically, after all.
Depending on what you're trying to accomplish, you might want to try defining multiple classes and just changing the className property in your js.
Setting the style, might be accomplished defining the inner-page style declaration.
Here is what i mean
var style = document.createElement('style');
style.type = 'text/css';
style.cssText = '.cssClass { color: #F00; }';
document.getElementsByTagName('head')[0].appendChild(style);
document.getElementById('someElementId').className = 'cssClass';
However the part of modifying it can be a lot of tricky than you think. Some regex solutions might do a good job. But here is another way, I found.
if (!document.styleSheets) return;
var csses = new Array();
if (document.styleSheets[0].cssRules) // Standards Compliant {
csses = document.styleSheets[0].cssRules;
}
else {
csses = document.styleSheets[0].rules; // IE
}
for (i=0;i<csses.length;i++) {
if ((csses[i].selectorText.toLowerCase()=='.cssClass') || (thecss[i].selectorText.toLowerCase()=='.borders'))
{
thecss[i].style.cssText="color:#000";
}
}
could you use jQuery on this? You could use
$(".class").css("property", val); /* or use the .width property */
There is a jQuery plugin called jQuery Rule,
http://flesler.blogspot.com/2007/11/jqueryrule.html
I tried it to dynamically set some div sizes of a board game. It works in FireFox, not in Chrome. I didn't try IE9.

How to check if a css rule exists

I need to check if a CSS rule exists because I want to issue some warnings if a CSS file is not included.
What is the best way of doing this?
I could filter through window.document.styleSheets.cssRules, but I'm not sure how cross-browser this is (plus I notice on Stack Overflow that object is null for styleSheet[0]).
I would also like to keep dependencies to a minimum.
Is there a straightforward way to do this? Do I just have to create matching elements and test the effects?
Edit: If not, what are the cross-browser concerns of checking window.document.styleSheets?
I don't know if this is an option for you, but if it's a single file you want to check, then you can write your error message and toggle the style to hide it in that file.
<span class="include_error">Error: CSS was not included!</span>
CSS file:
.include_error {
display: none;
visibility: hidden;
}
I test for proper CSS installation using javascript.
I have a CSS rule in my stylesheet that sets a particular id to position: absolute.
#testObject {position: absolute;}
I then programmatically create a temporary div with visibility: hidden with that ID and get the computed style position. If it's not absolute, then the desired CSS is not installed.
If you can't put your own rule in the style sheet, then you can identify one or more rules that you think are representative of the stylesheet and not likely to change and design a temporary object that should get those rules and test for their existence that way.
Or, lastly, you could try to enumerate all the external style sheets and look for a particular filename that is included.
The point here is that if you want to see if an external style sheet is included, you have to pick something about that style sheet that you can look for (filename or some rule in it or some effect it causes).
Here is what I got that works. It's similar to the answers by #Smamatti and #jfriend00 but more fleshed out. I really wish there was a way to test for rules directly but oh well.
CSS:
.my-css-loaded-marker {
z-index: -98256; /*just a random number*/
}
JS:
$(function () { //Must run on jq ready or $('body') might not exist
var dummyElement = $('<p>')
.hide().css({height: 0, width: 0})
.addClass("my-css-loaded-marker")
.appendTo("body"); //Works without this on firefox for some reason
if (dummyElement.css("z-index") != -98256 && console && console.error) {
console.error("Could not find my-app.css styles. Application requires my-app.css to be loaded in order to function properly");
}
dummyElement.remove();
});
I would use a css selector like this from within your jquery widget.
$('link[href$="my-app.css"]')
If you get a result back it means there is a link element that has a href ending with "my-app.css"
Next use this function to validate a specific css property on an element you are depending on. I would suggest something specific to you styles like the width of a container rather something random like -9999 zindex
var getStyle = function(el, styleProp) {
var x = !!el.nodeType ? el : document.getElementById(el);
if (x.currentStyle)
var y = x.currentStyle[styleProp];
else if (window.getComputedStyle)
var y = document.defaultView.getComputedStyle(x, null).getPropertyValue(styleProp);
return y;
}
Like this
getStyle($('#stats-container')[0], "width")
or
getStyle("stats-container", "width")
If you are worried about not being able to edit other people's stylesheets, you can proxy them through a stylesheet of your own, using import
#import url('http://his-stylesheet.css');
.hideErrorMessage{ ... }
This is enough if you just want to know if your code is trying to load the stylesheet but won't help if you need to know if the foreign stylesheet was then loaded correctly.

Categories

Resources