I'm trying to find a way to change stylesheets based on what season it is with jquery because at this point it is unknown if I can use php or ruby at all on this site. Thanks for your responses!
The simplest is to scope your CSS styles and add a class at a high level. I usually do this at the body element. The CSS looks like:
body.summer ul { background-color: green; }
body.fall ul { background-color: orange; }
body.winter ul { background-color: white; }
body.spring ul { background-color: pink; }
Then, use JS to set the body class:
...</body>
<script ...>
var season = (new Date()).getMonth...;
$('body').addClass(season);
</script>
</html>
As you can see, I placed this immediately after closing the body tag. I think this is the first place you can put it and get it to work, but you'll have to check. The reason to put it here is to prevent the flash of unstyled content-- if you have lots going on on the page, you'll want to execute this Javascript before the on ready callback. That being said, I actually haven't had much problem just putting most of my code in the ready callback.
You can also load different stylesheets easily-- probably at the same place. Just create a style node and insert it into the head as the last node. You'd do this if you have major differences between your styles. Pretty tricky to maintain.
$("head").append("<style type=\"text/css\" src=\"" + season + ".css\"">");
I would suggest you narrow down the items that you want to change on the page, since the CSS file would already be loaded and jQuery would just be applying the css after the static css is loaded. You could leave these specific style declarations out of the css or keep them as default. For example, if the background image changes, you could set it to white in the default css declaration. This way, on load, it looks normal and you're only using JavaScript to load necessary items.
You could then use the JavaScript month function to get the current month
var month = new Date();
month = month.getMonth();
Then, you could use jQuery to apply those styles to the head with the jQuery ready function. You could have a simple switch of if/else statement to select one of four statements depending on the month number. For example, if you want to change the background
$("head").append("<style type=\"text/css\">body {background-color: #FFF !important;}</style>");
Just a quick example, but it would make it more efficient than loading a whole sheet I think.
put all your declarations in one css at the form of
.someStyle{ color:blue;}
.summer .someStyle{color:yellow;}
.winter .someStyle{color:purple;}
...
all classes under .summer will override the default style for summer
then on the server/client when the page is ready - add this class to the body
the only problem with doing it at the client is that the default style will render first and then switch to the new one (just pick the season most common to your site's users - if it was Israel i would choose summer ;-)
Related
Basically, I have two Plotly Dash dropdowns. I loaded custom CSS upon page load like this. Each child of my select keywords dropdown selected has a designated color in my custom CSS. Now, I have another dropdown that I want to color dependent on the colors of the first dropdown. For example:
11797656 asset has the Agedwip keyword. So, I would like it to be red like the keyword Agedwip element. This is hard to achieve because the CSS I have been using is from a static file which is loaded only upon page load. So even if I know the color 11797656 should be, I cannot actually alter the CSS and make it that color as far as I know, since it would not read the file and update the CSS in the browser.
I figured using custom javascript would make this possible, if I could directly alter the browser's CSS as opposed to just the static file that I loaded as a stylesheet. The way I am thinking about this now is...create a javascript function that will alter the color of a specific element, find a library with a javascript interpreter that has Python bindings, call the javascript function from within Python and pass it the necessary values which should update my browser's CSS.
Example:
javascript function( child_index_num, color )
alter asset css with child_index_num to give it color I want
Here is the code I currently use, to define the keyword static CSS upon page load. There are many more elements, this is just the first 3 for sake of understanding how I do this:
#keyword-selection .Select--multi .Select-control .Select-multi-value-wrapper .Select-value:nth-child(1) {
background-color: rgb(228,26,28);
border-color: "grey";
color: #fff;
}
#keyword-selection .Select--multi .Select-control .Select-multi-value-wrapper .Select-value:nth-child(2) {
background-color: rgb(55,126,184);
border-color: "grey";
color: #fff;
}
#keyword-selection .Select--multi .Select-control .Select-multi-value-wrapper .Select-value:nth-child(3) {
background-color: rgb(77,175,74);
border-color: "grey";
color: #fff;
}
Essentially just a color for each spot that could possibly exist. Can someone validate my idea for coloring select assets prior to me trying it, or provide a better alternative? Or is this just not possible to do/would it slow down my website drastically to implement? I am a novice with Javascript, so this solution was a bit out of my comfort zone. Feedback would be appreciated, thank you!
The CSS I'm trying to remove from the iFrame (colours.css in phpbb)
html, body {
color: #536482;
background: url("../path/to/background.jpg") repeat-x #8fe909;
}
The iFrame:
<iframe id="commentframe" scrolling="no" name="commentframe" onload="iframeLoaded()" src="/forum/viewtopic.php?f=13&t=10">
This is also wrapped up in a div named #commentdiv just for easier handling of the span region. Here is also iframe-loaded, though I think it's irrelevant, people often ask for anything related to the code going on
<script type="text/javascript">
function iframeLoaded() {
var iFrameID = document.getElementById('commentframe');
if(iFrameID) {
// here you can make the height, I delete it first, then I make it again
iFrameID.height = "";
iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
}
}
</script>
As I understand it, I need to use the .has() jquery function to achieve this task by specifying a CSS class somewhere
.commentsbg {
background-color: transparent;
background: transparent;
}
Then the .has function something like this.
<script type="text/javascript">
$("body").has("iframe").addClass('commentsbg');
</script>
I also tried
<script type="text/javascript">
$("commentdiv").has("iframe").addClass('commentsbg');
</script>
as well as trying them in my string of .on('load', function)s. Honestly, I'm just very very confused as to where any of this is supposed to go. Does the js/jquery go in the CSS file (does this ever happen?)... And does the CSS go in colours.css (the original css file of the iframe)? I'm so lost on this one and been at it for quite some time.
There's a few things to comment:
<script type="text/javascript">
$("commentdiv").has("iframe").addClass('commentsbg');
</script>
Here you forgot the identifier or class for your commentDiv, so your function will not work (# for id and . for classes):
$("#commentdiv").has("iframe").addClass('commentsbg');
or
$(".commentdiv").has("iframe").addClass('commentsbg')
However, I think your are not approaching correctly to what you want to achieve. You can act directly to your desired tag.
Afterwards, CSS properties should modify CSS, so it's better to add a class to your <iframe> when it's loaded if you want and change it's properties in your CSS.
Your code is redundant, with background: transparent and with background-color: transparent, it's better to use:
.commentsbg {
background-color: transparent !important;
}
However, you can act directly to your <iframe> in your CSS, adding !important to remove default styles.
To simplify and summary things, you should modify the background of your iframe, firstly in your CSS (adding !important if needed, because JavaScript will load more your website).
If this doesn't work, try adding a class when you need (onload for example) and modify it's CSS.
My target is to have a list of file names, and near every item a picture of that file extension will appear next to it.
there is a nice way to do that:
p[icon^=".gif"]
{
background: url(images/gif.png) no-repeat center left)
}
this checks if the icon attribute of the 'p' element ends with .gif. if it does,
it applies the given style to that element.
but instead of define every file type, i want it to be generic since i have a folder with icons in this format: {file-extansion}.png
in case there is no matching file with the given extansion or there is no file extansion, there will be a default path of "default.png".
There is an option to do that or part of that? if no, what way you advise me doing that?
By the way I am not a css/javascript expert so please given enough details so I can understand your answers.
You can use jQuery library for this:
HTML
<p data-ext=".gif">Text</p>
<p data-ext=".png">Text</p>
<p data-ext=".jpg">Text</p>
CSS
p {
background-repeat: no-repeat;
background-position: 0 50%;
}
JavaScript
$("p[data-ext]").each(function() {
var ext = $(this).data("ext").substring(1);
$(this).css("background-image", "url(images/" + ext + ".png)");
});
It works so that you add data-ext attribute to each p (or whatever) tag. jQuery selects all p tags which have data-ext attribute, then gets attribute value, and changes background-image of each element.
DEMO: http://jsfiddle.net/AEsx4/
Using pure CSS, you can't dynamically reference attributes in the URL, but you can make them content. Here are some lame workarounds using pure CSS and finally a wishful thinking approach :(
Use a class
<div class="jpg">
</div>
/* css */
.jpg {
background: url("/img/jpg.jpg");
}
This works great, but you need one class per extension.
Use an attribute selector
<div data-ext="jpg"></div>
div[data-ext=jpg] {
background: url(/img/jpg.jpg);
}
For more on this approach see:
http://css-tricks.com/attribute-selectors/
I used data-ext, because in HTML you're not really supposed to add random tags, so the HTML creators gave us data-* which is valid HTML5 and we can do whatever want with it. Either way, you need to create a new CSS selector for every extension. Not good.
Closest you can get with pure css
<div data-ext="jpg"></div>
div:after {
content: attr(data-ext);
}
You will see the name of the extension next to the div. This almost works, but it's not quite good enough.
More about CSS Functions: http://www.suburban-glory.com/blog?page=130
What you actually want
<div data-ext="jpg"></div>
div:after {
content: url("/img/jpg." attr(data-ext));
}
Sadly this doesn't appear to work at the moment, but boy would it be awesome.
I have a webpage which heavily makes use of jQuery.
My goal is to only show the page when everything is ready.
With that I want to avoid showing the annoying page rendering to the user.
I tried this so far (#body_holder is a wrapper inside body):
$(function(){
$('#body_holder').hide();
});
$(window).load(function() {
$("#body_holder").show();
});
This works completely fine, but messes up the layout.
The problem is that hiding the wrapper interferes with the other jQuery functions and plugins used (eg layout-plugin).
So I guess there must be another trick to do this. Maybe lay a picture or div over the body until window.load has occurred?
What approaches do you use?
EDIT:
The solution most likely has to be another way than display:none or hide();
Anything done with jQuery will normally have to wait for document.ready, which is too late IMHO.
Put a div on top, like so:
<div id="cover"></div>
set some styles:
#cover {position: fixed; height: 100%; width: 100%; top:0; left: 0; background: #000; z-index:9999;}
and hide it with JS when all elements are loaded:
$(window).on('load', function() {
$("#cover").hide();
});
Or if for some reason your script uses even longer time then the DOM elements to load, set an interval to check the type of some function that loads the slowest, and remove the cover when all functions are defined!
$(window).on('load', function() {
$("#cover").fadeOut(200);
});
//stackoverflow does not fire the window onload properly, substituted with fake load
function newW()
{
$(window).load();
}
setTimeout(newW, 1000);
#cover {position: fixed; height: 100%; width: 100%; top:0; left: 0; background: #000; z-index:9999;
font-size: 60px; text-align: center; padding-top: 200px; color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>This</li>
<li>is</li>
<li>a</li>
<li>simple</li>
<li>test</li>
<li>of</li>
<li>a</li>
<li>cover</li>
</ul>
<div id="cover">LOADING</div>
Here is a jQuery solution for those looking:
Hide the body with css then show it after the page is loaded:
CSS:
html { visibility:hidden; }
JavaScript
$(document).ready(function() {
document.getElementsByTagName("html")[0].style.visibility = "visible";
});
The page will go from blank to showing all content when the page is loaded, no flash of content, no watching images load etc.
You should try setting visibility to hidden instead of display:none. Setting visibility to hidden will retain all elements positions and dimensions, thus it shouldn't create layout problems.
Start your HTML with:
<body style="opacity:0;">
At the end of your script:
document.body.style.opacity = 1;
Stumbled upon this and tried #9ete's solution but it didn't help me.
This worked instead:
CSS:
html { visibility:hidden; }
JS:
window.addEventListener('load', function () {
document.getElementsByTagName("html")[0].style.visibility = "visible";
});
As per documentation for window, the load event is fired after all the content (images included) is loaded while $document says that ready is fired after only the DOM is ready.
Your question is valid, but I would not get in a practice of hiding or covering the page while things are spinning up.
It keeps the user from understanding what's happening on the page. While lots of things may need to load, different parts of the page should spring to life as they're loaded. You should get in the practice of locking controls that are not ready, perhaps displaying a spinner or some other progress indicator over them. Or setting the cursor to wait on loading items.
This keeps the user in the loop and allows him to see and interact with parts as they come online instead of obscuring all parts until everything is ready.
You will normally want to load the things the user needs the quickest access to, usually stuff above the fold, first. Loading is a prioritization that can easily be coordinated with Promises.
At the very least seeing the page allows the user to get his bearings and decide what to do. Be transparent.
I was seeking a non-javascript solution so I found one that is working on most browsers in acceptable manner.
Since the loading order of CSS rules matters;
Define the hiding class in the first CSS file or inline in head.
.hidden-onpage-load{ display: none; }
In the body, the class can be used as
<div class="hidden-onpage-load"> ... </div>
Redefine it inline or in a CSS file after all other CSS and JS files are loaded
.hidden-onpage-load{ display: block; }
The simplest solution I've come up with is to wrap the body in a as suggested previously, but set it as hidden from the get go, then use JQuery (or javascript) to unhide on load after all components are loaded.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="bodyDiv" hidden>
Hello World!
</div>
<script>
$(document).ready(function() {
// add JQuery widget loads here
$("#bodyDiv").show(); // reveal complete page
})
</script>
Don't forget, a lot of frameworks use javascript to structure a page. To prevent the page from showing before these modification have been made you'll need to do something like what is described here (e.g. run a script at the end of the page to show the real contents of the page):
Detect if any JavaScript function is running
If you have a div #bodyholder then you can put display:none in your CSS for it and then with jQuery do:
$(document).ready(function() {
$('#body_holder').show();
});
I don't see why hiding a div should interfere with the loading of anything, because all it means is it is hidden. However, if you have lots of jQuery being used then make sure you wrap it in $(document).ready which will make sure that the DOM is fully loaded before the Javascript is executed
A further point is that HTML/CSS is designed for progressive loading, and if you do it properly then you can get a nice progressive loading of content for your users. I personally wouldn't want my users getting a white screen for a few seconds until everything was loaded. Move your Javascript to the end of the page so that it doesn't block loading and get content onto the screen as quickly as possible.
I have this thing on my webpage... I guess it could be called a widget...
How do I separate it's CSS and JS from the containing page's CSS and JS? preferably without using an iframe?
In my app the user can customize the CSS of the content, so, I'd need a clean slate.
On the outermost element of your widget, set a relatively unique class name. For example:
<div class="my_spiffy_widget">
<!-- Insert spiffy widget here -->
</div>
Put the Javascript and CSS in their own files. For the CSS, structure all of your selectors like this:
.my_spiffy_widget P { /* paragraph rules */ }
.my_spiffy_widget A { /* anchor rules */ }
.my_spiffy_widget UL { /* unordered list rules */ }
That ensures your rules do not accidentally get overridden by other CSS rules.
Likewise with the JavaScript, prefix your functions with a common, distinctive prefix:
function my_spiffy_widget_doSomething() {...}
Avoid global variables if possible, but if you cannot, prefix them as well:
var my_spiffy_widget_firstTime = true;
You could add the !important declaration in the properties, making it harder for the user to override the settings.
eg:
div.widget #header {
padding-left: 10px !important;
padding-right: 5px !important;
}
And/or you could grab a CSS reset script (such as Eric Meyer's) and preface each selector with the name of your container DIV.
You can give all elements outside very complex css class names and make sure they don't collide with the ones the user will choose (like "KAFHxyz_..."). This way, all sane class names and default styles will only apply to the "widget".
This will be some effort since you'll need to set all the standard CSS styles using !important (so the user can say "body { font ... }" and it will only apply to his area.
Alternatively, you could try to write some javascript which fetches all styles of all elements, then add the "widget" (and it's JS/CSS) and then reset all styles to what they were before. Should be possible but the performance will probably suck.
[EDIT] That said, you do know that you can create an iframe with JavaScript and manipulate the content (the DOM inside) to your hearts content, yes? In this scenario, the IFrame will just be a Div-like element which adds a "namespace" for CSS and JS files.