This is my website http://natjecanje.interes.hr/
I want to have big A and small A and by pressing one of this "A" people can change all letters size on website, all elements need change font size, Thank you! :)
P.S. I did google search, but i didn't find what i was looking for.
You need to use 2 differents CCS Style, a little JS script
Please Find below Javascript :
function setActiveStyleSheet(title) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
if (navigator.appName == "Microsoft Internet Explorer") {
window.resizeBy(0,-10);
window.resizeBy(0,+10);
}
}
function getActiveStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title");
}
return null;
}
function getPreferredStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("rel").indexOf("alt") == -1
&& a.getAttribute("title")
) return a.getAttribute("title");
}
return null;
}
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
window.onload = function(e) {
var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);
}
window.onunload = function(e) {
var title = getActiveStyleSheet();
createCookie("style", title, 365);
}
var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);
You can save this script in a fil named : changement_css.js
Now you need a first CCS style whit regular font-size, and another one with a different font size, and include it in your HTML file.
<!--Default CSS-->
<link rel="stylesheet" type="text/css" href="normal.css" title="normal">
<!--Alternate CSS-->
<link rel="alternate stylesheet" type="text/css" href="grand.css" title="grand">
Copy those line instead of your regular CSS
Then, use this code to call your JS after your CSS link :
<script language="JavaScript" src="changement_css.js" type="text/javascript"></script>
Then, you need a button to change font-size :
<ul>
<li>Normal</li>
<li>Grand</li>
</ul>
I hope this could help you.
This message is translate from : http://forum.alsacreations.com/topic-6-11551-1-Boutons-AugmenterDiminuer-la-Taille-du-Texte-.html
function promjenaVelicineFonta(inc)
{
var p = document.getElementsByTagName('p');
for(n=0; n<p.length; n++) {
if(p[n].style.fontSize) {
var size = parseInt(p[n].style.fontSize.replace("px", ""));
} else {
var size = 14;
}
p[n].style.fontSize = size+inc + 'px';
}
var span = document.getElementsByTagName('span');
for(n=0; n<span.length; n++) {
if(span[n].style.fontSize) {
var size = parseInt(span[n].style.fontSize.replace("px", ""));
} else {
var size = 14;
}
span[n].style.fontSize = size+inc + 'px';
}
}
I found a solution, here it is.
Do you mean font size (i.e. 10pt, 12pt etc) or font capitalisation (i.e. a or A)? I think you mean capitalisation based on the theme of your question (because you said 'big' and 'small')?
You can control capitalisation with CSS via the 'text-transform' property (http://www.w3schools.com/cssref/pr_text_text-transform.asp).
You can use JavaScript to add remove CSS classes which is outlined in this thread: Change an element's class with JavaScript
Using this approach you could add remove CSS classes which use text-transform to change the capitalisation of the font.
Related
I would like to read the text of my pages with SpeechSynthesisUtterance.
I found this script: https://www.hongkiat.com/blog/text-to-speech/
Almost perfect, but the pause button doesn't seem to do much, and I wish I had the ability to set a language and maybe choose a voice.
I found the reference here: https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance, but I'm not very knowledgeable in JavaScript.
For language, as far as I understand, should be used the lang parameter set in the html tag.
For the voice I have absolutely no idea of how to implement it in the code.
It would be important because I have texts in English, Spanish, French and Italian, and the result without voice and language settings sometimes sounds really weird.
Update
These days I fiddled a little, I managed (more or less) to combine two different scripts/examples.
This: https://www.hongkiat.com/blog/text-to-speech/
and this: https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis#Examples
The code that came out is this:
HTML
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="text-to-speech.js"></script>
</head>
<body>
<div class=buttons>
<button id=play></button>
<button id=pause></button>
<button id=stop></button>
</div>
<select id="voices">
</select>
<div id="description">
The SpeechSynthesis interface of the Web Speech API is the controller interface for the speech service; this can be used to retrieve information about the synthesis voices available on the device, start and pause speech, and other commands besides.
Questo è in italiano come viene?
</div>
</body>
</html>
CSS
#import url('https://fonts.googleapis.com/css?family=Crimson+Text');
.buttons {
margin-top: 25px;
}
button {
background: none;
border: none;
cursor: pointer;
height: 48px;
outline: none;
padding: 0;
width: 48px;
}
#play {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/play.svg);
}
#play.played {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/play1.svg);
}
#pause {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/pause.svg);
}
#pause.paused {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/pause1.svg);
}
#stop {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/stop.svg);
}
#stop.stopped {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/stop1.svg);
}
JAVASCRIPT
onload = function() {
if ('speechSynthesis' in window) with(speechSynthesis) {
// select voices////
var synth = window.speechSynthesis;
var voiceSelect = document.querySelector('#voices');
var voices = [];
function populateVoiceList() {
voices = synth.getVoices().sort(function (a, b) {
const aname = a.name.toUpperCase(), bname = b.name.toUpperCase();
if ( aname < bname ) return -1;
else if ( aname == bname ) return 0;
else return +1;
});
var selectedIndex = voiceSelect.selectedIndex < 0 ? 0 : voiceSelect.selectedIndex;
voiceSelect.innerHTML = '';
for(i = 0; i < voices.length ; i++) {
var option = document.createElement('option');
option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
if(voices[i].default) {
option.textContent += ' -- DEFAULT';
}
option.setAttribute('data-lang', voices[i].lang);
option.setAttribute('data-name', voices[i].name);
voiceSelect.appendChild(option);
}
voiceSelect.selectedIndex = selectedIndex;
}
populateVoiceList();
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = populateVoiceList;
}
//end select voices
var playEle = document.querySelector('#play');
var pauseEle = document.querySelector('#pause');
var stopEle = document.querySelector('#stop');
var flag = false;
playEle.addEventListener('click', onClickPlay);
pauseEle.addEventListener('click', onClickPause);
stopEle.addEventListener('click', onClickStop);
function onClickPlay() {
if (!flag) {
flag = true;
utterance = new SpeechSynthesisUtterance(document.querySelector('#description').textContent);
//utterance.voice = getVoices()[0];
//add voice//
var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
for(i = 0; i < voices.length ; i++) {
//if(voices[i].name === 'Google UK English Female') {
if(voices[i].name === selectedOption) {
utterance.voice = voices[i];
break;
}
}
voiceSelect.onchange = function(){
onClickStop();
stopEle.className = '';
onClickPlay();
playEle.className = 'played';
}
//and add voice
utterance.onend = function() {
flag = false;
playEle.className = pauseEle.className = '';
stopEle.className = 'stopped';
};
playEle.className = 'played';
stopEle.className = '';
speak(utterance);
}
if (paused) { /* unpause/resume narration */
playEle.className = 'played';
pauseEle.className = '';
resume();
}
}
function onClickPause() {
if (speaking && !paused) { /* pause narration */
pauseEle.className = 'paused';
playEle.className = '';
pause();
}
}
function onClickStop() {
if (speaking) { /* stop narration */
/* for safari */
stopEle.className = 'stopped';
playEle.className = pauseEle.className = '';
flag = false;
cancel();
}
}
}
else { /* speech synthesis not supported */
msg = document.createElement('h5');
msg.textContent = "Detected no support for Speech Synthesis";
msg.style.textAlign = 'center';
msg.style.backgroundColor = 'red';
msg.style.color = 'white';
msg.style.marginTop = msg.style.marginBottom = 0;
document.body.insertBefore(msg, document.querySelector('div'));
}
}
Now I have the play, stop and pause buttons (pauses still does not work) and I can select one of the voices from those available in the device.
Seems to work fine with chrome, maybe a little less with Firefox, (but I'm using Linux LMDE, maybe it's my fault). And after a while on Chrome stops talking. I don't know why, but it seems to me that I've seen someone maybe understand why in some of the thousands of web pages I've opened these days, I'll have to reopen them all.
It would be nice if the selected voice was saved in a cookie, so if I open another page the script starts with the last voice I selected (I have no idea how to do it in JavaScript)
Update 2
I made some other small steps forward and simplified.
It almost seems to work, not always the pause button, the big doubt I have now is that with chrome it does not seem to stop when I update or change pages, and it is really bad that when you change page he keeps reading the previous page.
HTML
<div id="SpeechSynthesis">
<div>
<button id=play>play</button>
<button id=pause>pause</button>
<button id=stop>stop</button>
</div>
<select id="voices">
</select>
</div>
<p id="texttospeech">
The SpeechSynthesis interface of the Web Speech API is the controller interface for the speech service; this can be used to retrieve information about the synthesis voices available on the device, start and pause speech, and other commands besides.
Questo è in italiano come viene?
</p>
JAVASCRIPT
onload = function() {
if ('speechSynthesis' in window){
var synth = speechSynthesis;
var flag = false;
//stop when change page ???(not sure)
if(synth.speaking){ /* stop narration */
/* for safari */
flag = false;
synth.cancel();
}
/* references to the buttons */
var playEle = document.querySelector('#play');
var pauseEle = document.querySelector('#pause');
var stopEle = document.querySelector('#stop');
/* click event handlers for the buttons */
playEle.addEventListener('click', onClickPlay);
pauseEle.addEventListener('click', onClickPause);
stopEle.addEventListener('click', onClickStop);
// select voices////
//var synth = window.speechSynthesis;
var voiceSelect = document.querySelector('#voices');
var voices = [];
function populateVoiceList() {
voices = synth.getVoices().sort(function (a, b) {
const aname = a.name.toUpperCase(), bname = b.name.toUpperCase();
if ( aname < bname ) return -1;
else if ( aname == bname ) return 0;
else return +1;
});
var selectedIndex = voiceSelect.selectedIndex < 0 ? 0 : voiceSelect.selectedIndex;
voiceSelect.innerHTML = '';
for(i = 0; i < voices.length ; i++) {
var option = document.createElement('option');
option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
if(voices[i].default) {
option.textContent += ' -- DEFAULT';
}
option.setAttribute('data-lang', voices[i].lang);
option.setAttribute('data-name', voices[i].name);
voiceSelect.appendChild(option);
}
voiceSelect.selectedIndex = selectedIndex;
}
populateVoiceList();
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = populateVoiceList;
}
//end select voices
function onClickPlay() {
if(!flag){
flag = true;
utterance = new SpeechSynthesisUtterance(document.querySelector('#texttospeech').textContent);
//utterance.voice = synth.getVoices()[0];
//add voice//
var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
for(i = 0; i < voices.length ; i++) {
//if(voices[i].name === 'Google UK English Female') {
if(voices[i].name === selectedOption) {
utterance.voice = voices[i];
break;
}
}
voiceSelect.onchange = function(){
onClickStop();
onClickPlay();
}
//and add voice
utterance.onend = function(){
flag = false;
};
synth.speak(utterance);
//fix stop after a while bug
let r = setInterval(() => {
console.log(speechSynthesis.speaking);
if (!speechSynthesis.speaking) {
clearInterval(r);
} else {
speechSynthesis.resume();
}
}, 14000);
//end fix stop after a while bug
}
if(synth.paused) { /* unpause/resume narration */
synth.resume();
}
}
function onClickPause() {
if(synth.speaking && !synth.paused){ /* pause narration */
synth.pause();
}
}
function onClickStop() {
if(synth.speaking){ /* stop narration */
/* for safari */
flag = false;
synth.cancel();
}
}
}
else {
msg = document.createElement('h5');
msg.textContent = "Detected no support for Speech Synthesis";
msg.style.textAlign = 'center';
msg.style.backgroundColor = 'red';
msg.style.color = 'white';
msg.style.marginTop = msg.style.marginBottom = 0;
document.body.insertBefore(msg, document.querySelector('#SpeechSynthesis'));
}
}
Update 3
I tried to add a cookie with the last selected voice. I added a couple of functions to manage the cookies, and I set the cookie in the onClickPlay() function.
//add voice//
var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
for(i = 0; i < voices.length ; i++) {
//if(voices[i].name === 'Google UK English Female') {
if(voices[i].name === selectedOption) {
utterance.voice = voices[i];
setCookie('SpeechSynthesisVoice',voices[i].name,30);
break;
}
}
Firefox sets the cookie without problems, chrome no (even if the file is on an online server).
Then I tried to set the voice saved in the cookie as "selected" in populateVoiceList() function:
//get cookie voice
var cookievoice = getCookie('SpeechSynthesisVoice');
//add selcted to option if if cookievoice
if (cookievoice === voices[i].name) {
option.setAttribute('selected', 'selected');
}
It works, I find the "selected" in the code, but it doesn't seem to be considered, it always starts talking with the first voice in the list, or the default one, I'm not sure, and not with the one that has the "selected".
The cookie functions I use:
//cookie functions
function setCookie(name, value, days) {
var expires = '',
date = new Date();
if (days) {
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = '; expires=' + date.toGMTString();
}
document.cookie = name + '=' + value + expires + '; path=/';
}
function getCookie(name) {
var cookies = document.cookie.split(';'),
length = cookies.length,
i,
cookie,
nameEQ = name + '=';
for (i = 0; i < length; i += 1) {
cookie = cookies[i];
while (cookie.charAt(0) === ' ') {
cookie = cookie.substring(1, cookie.length);
}
if (cookie.indexOf(nameEQ) === 0) {
return cookie.substring(nameEQ.length, cookie.length);
}
}
return null;
}
function eraseCookie(name) {
createCookie(name, '', -1);
}
I didn't receive much help, but somehow I managed to set up a small player that reads the text of a web page.
I did a little tutorial with a demo that explains what I did and how it works.
https://www.alebalweb-blog.com/85-text-to-speech-player-with-buttons-play-pause-stop-and-voice-choice.html
How about this line after the "for" loop?
voiceSelect.selectedIndex = selectedIndex;
If it's still here you're overriding your selection.
Try something like
if(cookievoice === voices[i].name) {
option.setAttribute('selected', 'selected');
selectedIndex = i;
}
I need to create a CSS stylesheet class dynamically in JavaScript and assign it to some HTML elements like - div, table, span, tr, etc and to some controls like asp:Textbox, Dropdownlist and datalist.
Is it possible?
It would be nice with a sample.
Here is an option:
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.cssClass { color: #f00; }';
document.getElementsByTagName('head')[0].appendChild(style);
document.getElementById('someElementId').className = 'cssClass';
<div id="someElementId">test text</div>
Found a better solution, which works across all browsers.
Uses document.styleSheet to add or replace rules. Accepted answer is short and handy but this works across IE8 and less too.
function createCSSSelector (selector, style) {
if (!document.styleSheets) return;
if (document.getElementsByTagName('head').length == 0) return;
var styleSheet,mediaType;
if (document.styleSheets.length > 0) {
for (var i = 0, l = document.styleSheets.length; i < l; i++) {
if (document.styleSheets[i].disabled)
continue;
var media = document.styleSheets[i].media;
mediaType = typeof media;
if (mediaType === 'string') {
if (media === '' || (media.indexOf('screen') !== -1)) {
styleSheet = document.styleSheets[i];
}
}
else if (mediaType=='object') {
if (media.mediaText === '' || (media.mediaText.indexOf('screen') !== -1)) {
styleSheet = document.styleSheets[i];
}
}
if (typeof styleSheet !== 'undefined')
break;
}
}
if (typeof styleSheet === 'undefined') {
var styleSheetElement = document.createElement('style');
styleSheetElement.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(styleSheetElement);
for (i = 0; i < document.styleSheets.length; i++) {
if (document.styleSheets[i].disabled) {
continue;
}
styleSheet = document.styleSheets[i];
}
mediaType = typeof styleSheet.media;
}
if (mediaType === 'string') {
for (var i = 0, l = styleSheet.rules.length; i < l; i++) {
if(styleSheet.rules[i].selectorText && styleSheet.rules[i].selectorText.toLowerCase()==selector.toLowerCase()) {
styleSheet.rules[i].style.cssText = style;
return;
}
}
styleSheet.addRule(selector,style);
}
else if (mediaType === 'object') {
var styleSheetLength = (styleSheet.cssRules) ? styleSheet.cssRules.length : 0;
for (var i = 0; i < styleSheetLength; i++) {
if (styleSheet.cssRules[i].selectorText && styleSheet.cssRules[i].selectorText.toLowerCase() == selector.toLowerCase()) {
styleSheet.cssRules[i].style.cssText = style;
return;
}
}
styleSheet.insertRule(selector + '{' + style + '}', styleSheetLength);
}
}
Function is used as follows.
createCSSSelector('.mycssclass', 'display:none');
Short answer, this is compatible "on all browsers" (specifically, IE8/7):
function createClass(name,rules){
var style = document.createElement('style');
style.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(style);
if(!(style.sheet||{}).insertRule)
(style.styleSheet || style.sheet).addRule(name, rules);
else
style.sheet.insertRule(name+"{"+rules+"}",0);
}
createClass('.whatever',"background-color: green;");
And this final bit applies the class to an element:
function applyClass(name,element,doRemove){
if(typeof element.valueOf() == "string"){
element = document.getElementById(element);
}
if(!element) return;
if(doRemove){
element.className = element.className.replace(new RegExp("\\b" + name + "\\b","g"));
}else{
element.className = element.className + " " + name;
}
}
Here's a little test page as well: https://gist.github.com/shadybones/9816763
The key little bit is the fact that style elements have a "styleSheet"/"sheet" property which you can use to to add/remove rules on.
There is a light jQuery plugin which allows to generate CSS declarations: jQuery-injectCSS
In fact, it uses JSS (CSS described by JSON), but it's quite easy to handle in order to generate dynamic css stylesheets.
$.injectCSS({
"#test": {
height: 123
}
});
YUI has by far the best stylesheet utility I have seen out there. I encourage you to check it out, but here's a taste:
// style element or locally sourced link element
var sheet = YAHOO.util.StyleSheet(YAHOO.util.Selector.query('style',null,true));
sheet = YAHOO.util.StyleSheet(YAHOO.util.Dom.get('local'));
// OR the id of a style element or locally sourced link element
sheet = YAHOO.util.StyleSheet('local');
// OR string of css text
var css = ".moduleX .alert { background: #fcc; font-weight: bold; } " +
".moduleX .warn { background: #eec; } " +
".hide_messages .moduleX .alert, " +
".hide_messages .moduleX .warn { display: none; }";
sheet = new YAHOO.util.StyleSheet(css);
There are obviously other much simpler ways of changing styles on the fly such as those suggested here. If they make sense for your problem, they might be best, but there are definitely reasons why modifying CSS is a better solution. The most obvious case is when you need to modify a large number of elements. The other major case is if you need your style changes to involve the cascade. Using the DOM to modify an element will always have a higher priority. It's the sledgehammer approach and is equivalent to using the style attribute directly on the HTML element. That is not always the desired effect.
As of IE 9. You can now load a text file and set a style.innerHTML property. So essentially you can now load a css file through ajax (and get the callback) and then just set the text inside of a style tag like this.
This works in other browsers, not sure how far back. But as long as you don't need to support IE8 then it would work.
// RESULT: doesn't work in IE8 and below. Works in IE9 and other browsers.
$(document).ready(function() {
// we want to load the css as a text file and append it with a style.
$.ajax({
url:'myCss.css',
success: function(result) {
var s = document.createElement('style');
s.setAttribute('type', 'text/css');
s.innerHTML = result;
document.getElementsByTagName("head")[0].appendChild(s);
},
fail: function() {
alert('fail');
}
})
});
and then you can have it pull an external file like the myCss.css
.myClass { background:#F00; }
Using google closure:
you can just use the ccsom module:
goog.require('goog.cssom');
var css_node = goog.cssom.addCssText('.cssClass { color: #F00; }');
The javascript code attempts to be cross browser when putting the css node into the document head.
Here is Vishwanath's solution slightly rewritten with comments :
function setStyle(cssRules, aSelector, aStyle){
for(var i = 0; i < cssRules.length; i++) {
if(cssRules[i].selectorText && cssRules[i].selectorText.toLowerCase() == aSelector.toLowerCase()) {
cssRules[i].style.cssText = aStyle;
return true;
}
}
return false;
}
function createCSSSelector(selector, style) {
var doc = document;
var allSS = doc.styleSheets;
if(!allSS) return;
var headElts = doc.getElementsByTagName("head");
if(!headElts.length) return;
var styleSheet, media, iSS = allSS.length; // scope is global in a function
/* 1. search for media == "screen" */
while(iSS){ --iSS;
if(allSS[iSS].disabled) continue; /* dont take into account the disabled stylesheets */
media = allSS[iSS].media;
if(typeof media == "object")
media = media.mediaText;
if(media == "" || media=='all' || media.indexOf("screen") != -1){
styleSheet = allSS[iSS];
iSS = -1; // indication that media=="screen" was found (if not, then iSS==0)
break;
}
}
/* 2. if not found, create one */
if(iSS != -1) {
var styleSheetElement = doc.createElement("style");
styleSheetElement.type = "text/css";
headElts[0].appendChild(styleSheetElement);
styleSheet = doc.styleSheets[allSS.length]; /* take the new stylesheet to add the selector and the style */
}
/* 3. add the selector and style */
switch (typeof styleSheet.media) {
case "string":
if(!setStyle(styleSheet.rules, selector, style));
styleSheet.addRule(selector, style);
break;
case "object":
if(!setStyle(styleSheet.cssRules, selector, style));
styleSheet.insertRule(selector + "{" + style + "}", styleSheet.cssRules.length);
break;
}
One liner, attach one or many new cascading rule(s) to the document.
This example attach a cursor:pointer to every button, input, select.
document.body.appendChild(Object.assign(document.createElement("style"), {textContent: "select, button, input {cursor:pointer}"}))
https://jsfiddle.net/xk6Ut/256/
One option to dynamically create and update CSS class in JavaScript:
Using Style Element to create a CSS section
Using an ID for the style element so that we can update the CSS
class
.....
function writeStyles(styleName, cssText) {
var styleElement = document.getElementById(styleName);
if (styleElement)
document.getElementsByTagName('head')[0].removeChild(
styleElement);
styleElement = document.createElement('style');
styleElement.type = 'text/css';
styleElement.id = styleName;
styleElement.innerHTML = cssText;
document.getElementsByTagName('head')[0].appendChild(styleElement);
}
...
var cssText = '.testDIV{ height:' + height + 'px !important; }';
writeStyles('styles_js', cssText)
An interesting project which could help you out in your task is JSS.
JSS is an authoring tool for CSS which allows you to use JavaScript to describe styles in a declarative, conflict-free and reusable way. It can compile in the browser, server-side or at build time in Node.
JSS library allows you to inject in the DOM/head section using the .attach() function.
Repl online version for evaluation.
Further information on JSS.
An example:
// Use plugins.
jss.use(camelCase())
// Create your style.
const style = {
myButton: {
color: 'green'
}
}
// Compile styles, apply plugins.
const sheet = jss.createStyleSheet(style)
// If you want to render on the client, insert it into DOM.
sheet.attach()
I was looking through some of the answers here, and I couldn't find anything that automatically adds a new stylesheet if there are none, and if not simply modifies an existing one that already contains the style needed, so I made a new function (should work accross all browsers, though not tested, uses addRule and besides that only basic native JavaScript, let me know if it works):
function myCSS(data) {
var head = document.head || document.getElementsByTagName("head")[0];
if(head) {
if(data && data.constructor == Object) {
for(var k in data) {
var selector = k;
var rules = data[k];
var allSheets = document.styleSheets;
var cur = null;
var indexOfPossibleRule = null,
indexOfSheet = null;
for(var i = 0; i < allSheets.length; i++) {
indexOfPossibleRule = findIndexOfObjPropInArray("selectorText",selector,allSheets[i].cssRules);
if(indexOfPossibleRule != null) {
indexOfSheet = i;
break;
}
}
var ruleToEdit = null;
if(indexOfSheet != null) {
ruleToEdit = allSheets[indexOfSheet].cssRules[indexOfPossibleRule];
} else {
cur = document.createElement("style");
cur.type = "text/css";
head.appendChild(cur);
cur.sheet.addRule(selector,"");
ruleToEdit = cur.sheet.cssRules[0];
console.log("NOPE, but here's a new one:", cur);
}
applyCustomCSSruleListToExistingCSSruleList(rules, ruleToEdit, (err) => {
if(err) {
console.log(err);
} else {
console.log("successfully added ", rules, " to ", ruleToEdit);
}
});
}
} else {
console.log("provide one paramter as an object containing the cssStyles, like: {\"#myID\":{position:\"absolute\"}, \".myClass\":{background:\"red\"}}, etc...");
}
} else {
console.log("run this after the page loads");
}
};
then just add these 2 helper functions either inside the above function, or anywhere else:
function applyCustomCSSruleListToExistingCSSruleList(customRuleList, existingRuleList, cb) {
var err = null;
console.log("trying to apply ", customRuleList, " to ", existingRuleList);
if(customRuleList && customRuleList.constructor == Object && existingRuleList && existingRuleList.constructor == CSSStyleRule) {
for(var k in customRuleList) {
existingRuleList["style"][k] = customRuleList[k];
}
} else {
err = ("provide first argument as an object containing the selectors for the keys, and the second argument is the CSSRuleList to modify");
}
if(cb) {
cb(err);
}
}
function findIndexOfObjPropInArray(objPropKey, objPropValue, arr) {
var index = null;
for(var i = 0; i < arr.length; i++) {
if(arr[i][objPropKey] == objPropValue) {
index = i;
break;
}
}
return index;
}
(notice that in both of them I use a for loop instead of .filter, since the CSS style / rule list classes only have a length property, and no .filter method.)
Then to call it:
myCSS({
"#coby": {
position:"absolute",
color:"blue"
},
".myError": {
padding:"4px",
background:"salmon"
}
})
Let me know if it works for your browser or gives an error.
Looked through the answers and the most obvious and straight forward is missing: use document.write() to write out a chunk of CSS you need.
Here is an example (view it on codepen: http://codepen.io/ssh33/pen/zGjWga):
<style>
#import url(http://fonts.googleapis.com/css?family=Open+Sans:800);
.d, body{ font: 3vw 'Open Sans'; padding-top: 1em; }
.d {
text-align: center; background: #aaf;
margin: auto; color: #fff; overflow: hidden;
width: 12em; height: 5em;
}
</style>
<script>
function w(s){document.write(s)}
w("<style>.long-shadow { text-shadow: ");
for(var i=0; i<449; i++) {
if(i!= 0) w(","); w(i+"px "+i+"px #444");
}
w(";}</style>");
</script>
<div class="d">
<div class="long-shadow">Long Shadow<br> Short Code</div>
</div>
For the benefit of searchers; if you are using jQuery, you can do the following:
var currentOverride = $('#customoverridestyles');
if (currentOverride) {
currentOverride.remove();
}
$('body').append("<style id=\"customoverridestyles\">body{background-color:pink;}</style>");
Obviously you can change the inner css to whatever you want.
Appreciate some people prefer pure JavaScript, but it works and has been pretty robust for writing/overwriting styles dynamically.
function createCSSClass(selector, style, hoverstyle)
{
if (!document.styleSheets)
{
return;
}
if (document.getElementsByTagName("head").length == 0)
{
return;
}
var stylesheet;
var mediaType;
if (document.styleSheets.length > 0)
{
for (i = 0; i < document.styleSheets.length; i++)
{
if (document.styleSheets[i].disabled)
{
continue;
}
var media = document.styleSheets[i].media;
mediaType = typeof media;
if (mediaType == "string")
{
if (media == "" || (media.indexOf("screen") != -1))
{
styleSheet = document.styleSheets[i];
}
}
else if (mediaType == "object")
{
if (media.mediaText == "" || (media.mediaText.indexOf("screen") != -1))
{
styleSheet = document.styleSheets[i];
}
}
if (typeof styleSheet != "undefined")
{
break;
}
}
}
if (typeof styleSheet == "undefined") {
var styleSheetElement = document.createElement("style");
styleSheetElement.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(styleSheetElement);
for (i = 0; i < document.styleSheets.length; i++) {
if (document.styleSheets[i].disabled) {
continue;
}
styleSheet = document.styleSheets[i];
}
var media = styleSheet.media;
mediaType = typeof media;
}
if (mediaType == "string") {
for (i = 0; i < styleSheet.rules.length; i++)
{
if (styleSheet.rules[i].selectorText.toLowerCase() == selector.toLowerCase())
{
styleSheet.rules[i].style.cssText = style;
return;
}
}
styleSheet.addRule(selector, style);
}
else if (mediaType == "object")
{
for (i = 0; i < styleSheet.cssRules.length; i++)
{
if (styleSheet.cssRules[i].selectorText.toLowerCase() == selector.toLowerCase())
{
styleSheet.cssRules[i].style.cssText = style;
return;
}
}
if (hoverstyle != null)
{
styleSheet.insertRule(selector + "{" + style + "}", 0);
styleSheet.insertRule(selector + ":hover{" + hoverstyle + "}", 1);
}
else
{
styleSheet.insertRule(selector + "{" + style + "}", 0);
}
}
}
createCSSClass(".modalPopup .header",
" background-color: " + lightest + ";" +
"height: 10%;" +
"color: White;" +
"line-height: 30px;" +
"text-align: center;" +
" width: 100%;" +
"font-weight: bold; ", null);
Here is my modular solution:
var final_style = document.createElement('style');
final_style.type = 'text/css';
function addNewStyle(selector, style){
final_style.innerHTML += selector + '{ ' + style + ' } \n';
};
function submitNewStyle(){
document.getElementsByTagName('head')[0].appendChild(final_style);
final_style = document.createElement('style');
final_style.type = 'text/css';
};
function submitNewStyleWithMedia(mediaSelector){
final_style.innerHTML = '#media(' + mediaSelector + '){\n' + final_style.innerHTML + '\n};';
submitNewStyle();
};
You basically anywhere in your code do:
addNewStyle('body', 'color: ' + color1); , where color1 is defined variable.
When you want to "post" the current CSS file you simply do submitNewStyle(),
and then you can still add more CSS later.
If you want to add it with "media queries", you have the option.
After "addingNewStyles" you simply use submitNewStyleWithMedia('min-width: 1280px');.
It was pretty useful for my use-case, as I was changing CSS of public (not mine) website according to current time. I submit one CSS file before using "active" scripts, and the rest afterwards (makes the site look kinda-like it should before accessing elements through querySelector).
This is what worked for me in Angular:
In HTML I have button with programmatically created CSS with specific ID:
<button [id]="'hoverbutton1'+item.key" [ngClass]="getHoverButtonClass()">
<mat-icon class="icon">open_in_new</mat-icon>
</button>
In typescript I created CSS and assign it to specific element with given ID:
addClasses(){
var style1 = document.createElement('style');
style1.innerHTML = '.hoverbutton'+this.item.key+' { display: none; }';
document.getElementsByTagName('head')[0].appendChild(style1);
}
getHoverButtonClass() {
return "hoverbutton"+this.item.key
}
This way I can create as many CSS classes as I want and assign them to elements individually. :)
I am a web design newb so I am not sure if this is the best forum or if there's some blindingly obvious solution that completely eludes me. So forgive me if either is the case.
So, here's the deal.
I am building a blog using craft cms and on my layout file I am using a styleswitcher.js script to switch between two css files.
<head>
<link rel="stylesheet" type="text/css" media="screen" href="http://www.example.com/weblog1.css"/>
<link rel="stylesheet" type="text/css" media="screen" title="aeroplaniko" href="http://www.example.com/weblog1.css"/>
<link rel="alternate stylesheet" type="text/css" media="screen" title="white" href="http://www.example.com/weblog3.css" />
<script type="text/javascript" src="http://www.example.com/jquery-1.12.1.min.js" ></script>
<script type="text/javascript" src="http://www.example.com/styleswitcher.js">
</head>
<body>
</body>
I am also using css styles in order to deploy social media icons. So for example, facebook looks like this:
.facebook {
margin-right: 2px;
width: 28px;
height: 28px;
display:inline-block;
background-repeat:no-repeat;
background-image: url('logos/facebook.png');
background-size:28px 28px;
background-position:center bottom;
}
.facebook:hover {
background-image: url('logos/facebookhover.png');
}
Once I noticed that Internet Explorer is bad at displaying png files, I decided to switch to svg files. After some work, I was able to convert my png files to svg. I also changed all the png files referenced on my stylesheets to svg.
Here's the problem however. As soon as I use the css stylesheets which include the svg files, switching between styles only affects the particular page in which I made the switch and not the whole site.
So if I switch styles on the main page and then I go to an article page, I see the previous stylesheet. Sometimes, the style changes even when I go through paginated pages.
So, what's wrong and how can I fix it?
PS. I should note that I noticed the same problem even with png files when I was testing my website on my ipad.
PS2. Ok, here's the code in the styleswitcher.js file:
function setActiveStyleSheet(title) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
}
function getActiveStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title");
}
return null;
}
function getPreferredStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("rel").indexOf("alt") == -1
&& a.getAttribute("title")
) return a.getAttribute("title");
}
return null;
}
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
window.onload = function(e) {
var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);
}
window.onunload = function(e) {
var title = getActiveStyleSheet();
createCookie("style", title, 365);
}
var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);
I'm building a website template for primarily text content.
I would like to have two user switchable color schemes.
One dark background/light text and one light background/dark text to suit different viewing conditions.
How do I plan and design it such that user can toggle color scheme with a click of button and have cookie memorize the user's preference?
Without breaking the design, I would also like to let the user be able to increase the font-size and line-height for certain content block, eg. <div id="article"></font>
Is this feasible?
#GamerNebulae #EliTownsend After studying the answer and making some modification, I come up with a solution that works for my situation.
Not sure if it's heavy when it comes to execution. Any advice for further improvement is appreciated.
CSS
body.dark {
background: #222;
color: #777;
}
HTML
Switch
Javscript
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
createCookie(name,"",-1);
}
function changeTheme() {
if (jQuery("body").hasClass("dark")) {
jQuery("body").removeClass("dark");
createCookie('theme', 'regular', 7);
}
else {
jQuery("body").addClass("dark");
createCookie('theme', 'dark', 7);
}
}
// initialize page, apply theme color by checking cookie variable 'theme'
var theme = readCookie('theme');
if(theme == "dark") jQuery("body").addClass("dark");
else if (theme == "regular") jQuery("body").removeClass("dark");
else if (jQuery("body").hasClass("dark")) createCookie('theme', 'dark', 7);
Stylesheets
<link rel="stylesheet" type="text/css" title="blue" href="http://example.com/css/blue.css">
<link rel="alternate stylesheet" type="text/css" title="pink" href="http://example.com/css/pink.css">
HTML
<form>
<input type="submit" onclick="switch_style('blue');return false;" name="theme" value="Blue Theme" id="blue">
<input type="submit" onclick="switch_style('pink');return false;" name="theme" value="Pink Theme" id="pink">
</form>
Javascript
//TO BE CUSTOMISED
var style_cookie_name = "style" ;
var style_cookie_duration = 30 ;
var style_domain = "thesitewizard.com" ;
// END OF CUSTOMISABLE SECTION
// You do not need to customise anything below this line
function switch_style ( css_title )
{
// You may use this script on your site free of charge provided
// you do not remove this notice or the URL below. Script from
// http://www.thesitewizard.com/javascripts/change-style-sheets.shtml
var i, link_tag ;
for (i = 0, link_tag = document.getElementsByTagName("link") ;
i < link_tag.length ; i++ ) {
if ((link_tag[i].rel.indexOf( "stylesheet" ) != -1) &&
link_tag[i].title) {
link_tag[i].disabled = true ;
if (link_tag[i].title == css_title) {
link_tag[i].disabled = false ;
}
}
set_cookie( style_cookie_name, css_title,
style_cookie_duration, style_domain );
}
}
function set_style_from_cookie()
{
var css_title = get_cookie( style_cookie_name );
if (css_title.length) {
switch_style( css_title );
}
}
function set_cookie ( cookie_name, cookie_value,
lifespan_in_days, valid_domain )
{
// http://www.thesitewizard.com/javascripts/cookies.shtml
var domain_string = valid_domain ?
("; domain=" + valid_domain) : '' ;
document.cookie = cookie_name +
"=" + encodeURIComponent( cookie_value ) +
"; max-age=" + 60 * 60 *
24 * lifespan_in_days +
"; path=/" + domain_string ;
}
function get_cookie ( cookie_name )
{
// http://www.thesitewizard.com/javascripts/cookies.shtml
var cookie_string = document.cookie ;
if (cookie_string.length != 0) {
var cookie_value = cookie_string.match (
'(^|;)[\s]*' +
cookie_name +
'=([^;]*)' );
return decodeURIComponent ( cookie_value[2] ) ;
}
return '' ;
}
I found this located here How to Use Javascript to Change a CSS
How do I refresh the page using Javascript without the page returning to
the top.
My page refreshes using a timer but the problem is it goes back to the top every time it reloads. It should be able to retain the current position of the page as it reloads.
P.S.
Additional mouse events are welcome if necessary to be a part of your suggestion.
I'm actually thinking of #idname to target on refresh but my HTML elements don't have IDs, only classes.
If you use JavaScript, this code will do the trick.
var cookieName = "page_scroll";
var expdays = 365;
// An adaptation of Dorcht's cookie functions.
function setCookie(name, value, expires, path, domain, secure) {
if (!expires) expires = new Date();
document.cookie = name + "=" + escape(value) +
((expires == null) ? "" : "; expires=" + expires.toGMTString()) +
((path == null) ? "" : "; path=" + path) +
((domain == null) ? "" : "; domain=" + domain) +
((secure == null) ? "" : "; secure");
}
function getCookie(name) {
var arg = name + "=";
var alen = arg.length;
var clen = document.cookie.length;
var i = 0;
while (i < clen) {
var j = i + alen;
if (document.cookie.substring(i, j) == arg) {
return getCookieVal(j);
}
i = document.cookie.indexOf(" ", i) + 1;
if (i == 0) break;
}
return null;
}
function getCookieVal(offset) {
var endstr = document.cookie.indexOf(";", offset);
if (endstr == -1) endstr = document.cookie.length;
return unescape(document.cookie.substring(offset, endstr));
}
function deleteCookie(name, path, domain) {
document.cookie = name + "=" +
((path == null) ? "" : "; path=" + path) +
((domain == null) ? "" : "; domain=" + domain) +
"; expires=Thu, 01-Jan-00 00:00:01 GMT";
}
function saveScroll() {
var expdate = new Date();
expdate.setTime(expdate.getTime() + (expdays*24*60*60*1000)); // expiry date
var x = document.pageXOffset || document.body.scrollLeft;
var y = document.pageYOffset || document.body.scrollTop;
var data = x + "_" + y;
setCookie(cookieName, data, expdate);
}
function loadScroll() {
var inf = getCookie(cookieName);
if (!inf) { return; }
var ar = inf.split("_");
if (ar.length == 2) {
window.scrollTo(parseInt(ar[0]), parseInt(ar[1]));
}
}
This works by using a cookie to remember the scroll position.
Now just add
onload="loadScroll()" onunload="saveScroll()"
to your body tag and all will be well.
Source(s): http://www.huntingground.freeserve.co.uk/main/mainfram.htm?../scripts/cookies/scrollpos.htm
If there is a certain set of specific sections of the page that are possible initial "scroll to" points, then you can assign those sections CSS ids and refresh the page with an appended ID hash at the end. For example, window.location = http://example.com#section2 will reload the page and automatically scroll it down to the element with the id "section2".
If it's not that specific, you can grab the current scroll position prior to refresh using jQuery's .scrollTop() method on the window: $(window).scrollTop(). You can then append this to the refresh URL, and include JS on the page that checks for this in order to automatically scroll to the correct position upon page load:
Grab current scroll position
var currentScroll = $(window).scrollTop();
window.location = 'http://example.com#' + currentScroll;
JS that must run when DOM is ready in order to check for a currentScroll hash
$(function(){
if(window.location.hash !== ''){
var scrollPos = parseInt(window.location.hash.substring(1),10);
$(window).scrollTo(scrollPos);
}
});
If you don't like the idea of modifying the URL in the address bar (because you really want to hide what you're doing from the user for some reason), you could store the scrollTo() value in a cookie instead of the URL.
You can do it using a cookie based method:
<html>
<head>
<script type="text/javascript">
var refreshPeriod = 120; // 120 Seconds
function refresh()
{
document.cookie = 'scrollTop=' + filterScrollTop();
document.cookie = 'scrollLeft=' + filterScrollLeft();
document.location.reload(true);
}
function getCookie(name)
{
var start = document.cookie.indexOf(name + "=");
var len = start + name.length + 1;
if(((!start) && (name != document.cookie.substring(0, name.length))) || start == -1)
return null;
var end = document.cookie.indexOf(";", len);
if(end == -1)
end = document.cookie.length;
return unescape(document.cookie.substring(len, end));
}
function deleteCookie(name)
{
document.cookie = name + "=" + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}
function setupRefresh()
{
var scrollTop = getCookie("scrollTop");
var scrollLeft = getCookie("scrollLeft");
if (!isNaN(scrollTop))
{
document.body.scrollTop = scrollTop;
document.documentElement.scrollTop = scrollTop;
}
if (!isNaN(scrollLeft))
{
document.body.scrollLeft = scrollLeft;
document.documentElement.scrollLeft = scrollLeft;
}
deleteCookie("scrollTop");
deleteCookie("scrollLeft");
setTimeout("refresh()", refreshPeriod * 1000);
}
function filterResults(win, docEl, body)
{
var result = win ? win : 0;
if (docEl && (!result || (result > docEl)))
result = docEl;
return body && (!result || (result > body)) ? body : result;
}
// Setting the cookie for vertical position
function filterScrollTop()
{
var win = window.pageYOffset ? window.pageYOffset : 0;
var docEl = document.documentElement ? document.documentElement.scrollTop : 0;
var body = document.body ? document.body.scrollTop : 0;
return filterResults(win, docEl, body);
}
// Setting the cookie for horizontal position
function filterScrollLeft()
{
var win = window.pageXOffset ? window.pageXOffset : 0;
var docEl = document.documentElement ? document.documentElement.scrollLeft : 0;
var body = document.body ? document.body.scrollLeft : 0;
return filterResults(win, docEl, body);
}
</script>
</head>
<body onload="setupRefresh()">
<!-- content here -->
</body>
</html>
or you can do it with a form method:
<html>
<head>
<script type="text/javascript">
// Saves scroll position
function scroll(value)
{
var hidScroll = document.getElementById('hidScroll');
hidScroll.value = value.scrollTop;
}
// Moves scroll position to saved value
function scrollMove(el)
{
var hidScroll = document.getElementById('hidScroll');
document.getElementById(el).scrollTop = hidScroll.value;
}
</script>
</head>
<body onload="scrollMove('divScroll');" onunload="document.forms(0).submit()";>
<form>
<input type="text" id="hidScroll" name="a"><br />
<div id="divScroll" onscroll="scroll(this);"
style="overflow:auto;height:100px;width:100px;">
<!-- content here -->
</div>
</form>
</body>
</html>
Just depends on your application's requirements and restrictions.
I would recommend refreshing only the part of the page you are interested in changing, using ajax. I mean, just replacing the content using javascript depending on the response of the ajax call. I would say you take a look at jQuery's ajax or get methods.
If you can give more information about what you are trying to do maybe I can be of more assistance. Anyway, I hope this helps a little bit.
Cheers!