I am a novice JavaScript programmer; any help would be greatly appreciated.
I have successfully implemented a script that allows users to switch from a "regular view" to a "high contrast view". The script is simply changing stylesheets.
I have also set up the script with a basic toggle: when a user clicks "High Contrast View" the link text changes to "Back".
However, I need to modify how the toggle works: rather than changing the link text, I need to change the link color.
I know that I can create a function with .style.color, but I am not sure how to integrate this in to my current script.
JavaScript:
function load_all() {
var cssval;
cssval = get_cookie("cssclass");
if (cssval == null || (cssval != "Normal CSS" && cssval != "High-Contrast-View")) {
cssval = "Normal CSS";
}
set_stylesheet(cssval);
}
function switchStyle(newtitle) {
set_stylesheet(newtitle);
finish_stylesheet();
}
function set_stylesheet(newtitle) {
var csslink;
if (newtitle == null) {
if (get_stylesheet() == "Normal CSS") newtitle = "High-Contrast-View";
else newtitle = "Normal CSS";
}
for (var i = 0; (csslink = document.getElementsByTagName("link")[i]); i++) {
if (csslink.getAttribute("rel").indexOf("style") != -1 && csslink.getAttribute("title")) {
csslink.disabled = true;
if (csslink.getAttribute("title") == newtitle)
csslink.disabled = false;
}
}
set_cookie("cssclass", newtitle, 28);
}
function finish_stylesheet() {
var nojsanchor, nojsspan, newtitle;
newtitle = get_stylesheet();
nojsanchor = document.getElementById("footer_nojslink");
nojsspan = document.getElementById("contrastToggle");
if (nojsanchor != null && nojsspan != null) {
while (nojsspan.hasChildNodes())
nojsspan.removeChild(nojsspan.childNodes[0]);
nojsspan.appendChild(document.createTextNode(newtitle == "Normal CSS" ? "high contrast" : "back"));
nojsanchor.href = "javascript:switchStyle('" + (newtitle == "Normal CSS" ? "High-Contrast-View" : "Normal CSS") + "')";
}
}
function get_stylesheet() {
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 accepts_cookies() {
document.cookie = "cookiecheck=true; path=/";
var cookies = document.cookie;
if (cookies.indexOf("cookiecheck") >= 0)
return true;
else
return false;
}
function set_cookie(name, value, days) {
var expire;
if (days > 0) {
expire = new Date();
expire.setDate(expire.getDate() + days);
}
else
expire = null;
document.cookie = name + "=" + escape(value) + (expire == null ? "" : ";expires=" + expire.toGMTString()) + ";path=/";
}
function get_cookie(name) {
var cookielist, cookie;
cookielist = document.cookie.split(";");
for (var i = 0; i < cookielist.length; i++) {
cookie = cookielist[i];
while (cookie.charAt(0) == " ")
cookie = cookie.substring(1);
if (cookie.indexOf(name + "=") == 0)
return unescape(cookie.substring(name.length + 1));
}
return null;
}
With your current code you should be able to do this:
document.getElementById("footer_nojslink").style.color = "#A6A6A6";
If you find yourself doing this kind of task frequently it's going to be worth your time to learn jQuery. It can sometimes make things simpler, and takes away most cross browser headaches. Here is a jQuery example for the specific example you are asking, changing link color;
$('#footer_nojslink').css('color','#A6A6A6');
easy
import the two (or more) stylesheets...
<head>
<link rel="stylesheet" href="style_1.css">
<link rel="stylesheet" href="style_2.css">
</head>
and then enable/disable them this way:
<script>
document.styleSheets[0].disabled=true;
document.styleSheets[1].enabled=true;
</script>
Now you can change the entire style of your site, not only the links.
https://developer.mozilla.org/En/DOM/Document.styleSheets
Related
This script rotate 5 pop'up tags, display one pop'up for every webpage manual refresh.
i want the script rotate automaticly one pop'up tag every 60 seconds.
if someone genius can make it i will be very grateful for him
Regards
<script language="JavaScript">
<!--
var frequencyCap = 12;
function setCookie(cookieName,cookieValue, expirehours) {
if (frequencyCap > 0) {
var today = new Date();
var expire = new Date();
expire.setTime(today.getTime() + 10000 * frequencyCap);
document.cookie = cookieName+"="+escape(cookieValue) + ";expires="+expire.toGMTString();
} else {
document.cookie = cookieName+"="+escape(cookieValue);
}
}
function ReadCookie(cookieName) {
var theCookie=""+document.cookie;
var ind=theCookie.indexOf(cookieName);
if (ind==-1 || cookieName=="") return "";
var ind1=theCookie.indexOf(';',ind);
if (ind1==-1) ind1=theCookie.length;
return unescape(theCookie.substring(ind+cookieName.length+1,ind1));
}
if (ReadCookie('cookie1') != '1') {
setCookie('cookie1','1', frequencyCap);
document.write("TAG POPUP-1");
}else if (ReadCookie('cookie2') != '1') {
setCookie('cookie2','1', frequencyCap);
document.write("TAG POPUP-2");
}else if (ReadCookie('cookie3') != '1') {
setCookie('cookie3','1', frequencyCap);
document.write("TAG POPUP-3");
}else if (ReadCookie('cookie4') != '1') {
setCookie('cookie4','1', frequencyCap);
document.write("TAG POPUP-4");
}else if (ReadCookie('cookie5') != '1') {
setCookie('cookie5','1', frequencyCap);
document.write("TAG POPUP-5");
}
// -->
</script>
Here is a simple timer function. All you'll need to do is put in your code to switch the popup tags
var timer = setInterval(rotate, 60000);
var idx = 0;
function rotate() {
if (idx++ < 5) {
//Insert code to switch popup tags
document.getElementById("demo").innerHTML = "Index: " + idx;
// ^ demo of timer working
if (idx >= 5)
idx = 0;
}
}
https://jsfiddle.net/3t7nqpg7/1/
I have an iframe:
<iframe id="msgContainer" sandbox="allow-same-origin"></iframe>
and I'd like to insert HTML into it, but not let any JavaScript that may be contained in the HTML run (this includes both <script> tags and on* attributes. I know how to insert HTML (just use document.getElementById('msgContainer').contentDocument.body.innerHTML=myHTML but I'd like to prevent any JS in myHTML from running. The way I've tried to do this is by using the sandbox attribute and only allowing same-origin, but JS still runs. Is there any way to do this?
Thanks
I couldn't find any answer other than to parse out the JS from an html string inserted into the iframe. Here's my code (if it helps anyone else):
/** Removes javascript from html string
* html: the string to be cleaned
*/
function clean(html) {
function stripHTML(){
html = html.slice(0, strip) + html.slice(j);
j = strip;
strip = false;
}
var strip = false,
lastQuote = false,
tag = false;
const prefix = "ANYTHING",
sandbox = " sandbox=''";
for(var i=0; i<html.length; i++){
if(html[i] === "<" && html[i+1] && isValidTagChar(html[i+1])) {
i++;
tag = false;
/* Enter element */
for(var j=i; j<html.length; j++){
if(!lastQuote && html[j] === ">"){
if(strip) {
stripHTML();
}
/* sandbox iframes */
if(tag === "iframe"){
var index = html.slice(i, j).toLowerCase().indexOf("sandbox");
if(index > 0) {
html = html.slice(0, i+index) + prefix + html.slice(i+index);
j += prefix.length;
}
html = html.slice(0, j) + sandbox + html.slice(j);
j += sandbox.length;
}
i = j;
break;
}
if(!tag && html[j] === " "){
tag = html.slice(i, j).toLowerCase();
}
if(lastQuote === html[j]){
lastQuote = false;
continue;
}
if(!lastQuote && html[j-1] === "=" && (html[j] === "'" || html[j] === '"')){
lastQuote = html[j];
}
/* Find on statements */
if(!lastQuote && html[j-2] === " " && html[j-1] === "o" && html[j] === "n"){
strip = j-2;
}
if(strip && html[j] === " " && !lastQuote){
stripHTML();
}
}
}
}
html = stripScripts(html);
return html;
}
/** Returns whether or not the character is a valid first character in a tag
* str: the first character
*/
function isValidTagChar(str) {
return str.match(/[a-z?\\\/!]/i);
}
/** Strips scripts from a string of html
* html: the string of html to be stripped
*/
// NOTE: <script> tags won't run in this context
function stripScripts(html) {
var div = document.createElement('div');
div.innerHTML = html;
var scripts = div.getElementsByTagName('script');
var i = scripts.length;
while (i--) {
scripts[i].parentNode.removeChild(scripts[i]);
}
return div.innerHTML;
}
I am totally novice for JS and cookies. I got this code online and tried to change it for 30 days (it was set to 365) but it's probably resetting the cookie for every page and the pop up appears if I go to other page or even return back to the original page. Only things I changed in the code was expire days to 30 and load delay of 30 secs.
It seems either it's resetting the cookie every time I move to other page or some other problem which I don't understand yet :). I was wondering if there is some more efficient way to have it rather putting the code in every html article page. Something like setting up a cookie in headers or something and recalling using body onload.
Here is the code:
<SCRIPT language=JavaScript>
<!--
var expDays = 30; // number of days the cookie should last
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 SetCookie (name, value,expires) {
var argv = SetCookie.arguments;
var argc = SetCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;
var path = (argc > 3) ? argv[3] : null;
var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
document.cookie = name + "=" + escape (value) +
((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
((path == null) ? "" : ("; path=" + path)) +
((domain == null) ? "" : ("; domain=" + domain)) +
((secure == true) ? "; secure" : "");
}
function DeleteCookie (name) {
var exp = new Date();
exp.setTime (exp.getTime() - 1);
var cval = GetCookie (name);
document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();
}
var exp = new Date();
exp.setTime(exp.getTime() + (expDays*24*60*60*1000));
function getCookieVal(offset) {
var endstr = document.cookie.indexOf (";", offset);
if (endstr == -1)
endstr = document.cookie.length;
return unescape(document.cookie.substring(offset, endstr));
}
function checkCount() {
var count = GetCookie('poponce');
if (count == null) {
count++;
SetCookie('poponce', count, exp);
// Action to take
dothis()
}
}
setTimeout(function dothis(){
var windowprops = "left=300,top=240,width=600,height=400,location=no,toolbar=no,menubar=no,scrollbars=no";
window.open("/subscribepopup.html", "", windowprops); // Use to load a page
}, 30000);
// -->
</SCRIPT>
<body OnLoad="checkCount()">
Ok a friend gave me this code, and it doesn't work. I have been looking for a java stylesheet changer, and this is the only one I can find. When I click on the link (to change the style) nothing happens. Help? And I do have trouble understanding javascript so it is difficult for me.
js code:
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);
}
);
Header Stylesheet Code:
<link rel="stylesheet" type="text/css" media="screen" href="css/zerohour.css" title="default" />
<link rel="alternate stylesheet" type="text/css" media="screen" href="css/rainbow.css" title="rainbow" />
Link Activator Code:
<a href="#"
onclick="setActiveStyleSheet('default');
return false;">change style to default</a>
<a href="#"
onclick="setActiveStyleSheet('rainbow');
return false;">change style to rainbow</a>
Here is a re-write of what I think you are trying to do:
var activeStylesheet = (function() {
// Store title of default linked stylesheet
var defaultTitle;
return {
// Set the active stylesheet to the link styesheet element with title
// Set all others to disabled
setActive: function(title) {
var link, links = document.getElementsByTagName('link');
for (var i=0, iLen=links.length; i<iLen; i++) {
link = links[i];
if (link.rel.indexOf("style") != -1 && link.title) {
link.disabled = true;
if (link.title == title) {
link.disabled = false;
}
}
}
},
// Return the title of the currently active linked stylesheet,
// or undefined if none found
getActive: function() {
var link, links = document.getElementsByTagName('link');
for (var i=0, iLen=links.length; i<iLen; i++) {
link = links[i];
if (link.rel.indexOf("style") != -1 &&
link.title &&
!link.disabled) {
return link.title;
}
}
},
// Return the title of the link stylesheet element where
// rel property contains 'alt'
getPreferred: function() {
var link, links = document.getElementsByTagName('link');
for (var i=0, iLen=links.length; i<iLen; i++) {
link = links[i];
if (link.rel.indexOf("style") != -1 &&
link.rel.indexOf('alt') == -1 &&
link.title) {
defaultTitle = title;
return link.title;
}
}
}
};
}());
Some buttons to do stuff:
<button onclick="
alert(activeStylesheet.getActive());
">Show title of active stylesheet</button>
<button onclick="
activeStylesheet.setActive('rainbow');
">Set active stylesheet to "rainbow"</button>
<button onclick="
activeStylesheet.setActive('default');
">Set active stylesheet to "default"</button>
Note that using the title will be case sensitive, so be careful.
You can store the title of the default linked stylesheet in the defaultTitle variable, but I don't know what you want to do with it. You have a setPreferred that first checks that defaultTitle is set and if not, calls getPreferred, calls setActive with defaultTitle.
I realize that this question isn't tagged Jquery but unless you have a strong reason to stick with vanilla Javascript, I would recommend Jquery.
You can switch styles in just two lines of code:
$('#foobar').click(function(){
$('link').attr('href','newstyle.css');
return false;
});
Live Demo
When the following codes are running, it makes the browser freeze for a couple of secondes.
How could i prevent that ? Thanks
function rsfp_changePage(formId, page, totalPages, validate)
{
if (validate)
{
var form = rsfp_getForm(formId);
if (!ajaxValidation(form, page))
return false;
}
for (var i=0; i<=totalPages; i++)
{
var thePage = document.getElementById('rsform_' + formId + '_page_' + i);
if (thePage)
document.getElementById('rsform_' + formId + '_page_' + i).style.display = 'none';
}
var thePage = document.getElementById('rsform_' + formId + '_page_' + page);
if (thePage)
{
thePage.style.display = '';
try {
eval('if (typeof rsfp_showProgress_' + formId + ' == "function") rsfp_showProgress_' + formId + '(' + page + ')');
}
catch (err) { }
}
}
...
You will find the form on http://www.ocsl.ch/dev
username : stackoverflow /
password : stackoverflow
Login first and then go to http://www.ocsl.ch/dev/sejour-linguistique/adultes/demande-d-offre-en-ligne
Once on this page, click on the green button "suivant" and you will see that it freezes for a very little will.
Below the content form the script.js file which contain the ajaxvalidation fonction.
Hope that helps a bit. Please ask if you need any thing else that may help.
function refreshCaptcha(componentId, captchaPath)
{
if(!captchaPath) captchaPath = 'index.php?option=com_rsform&task=captcha&componentId=' + componentId;
document.getElementById('captcha' + componentId).src = captchaPath + '&' + Math.random();
document.getElementById('captchaTxt' + componentId).value='';
document.getElementById('captchaTxt' + componentId).focus();
}
function number_format(number, decimals, dec_point, thousands_sep)
{
var n = number, prec = decimals;
n = !isFinite(+n) ? 0 : +n;
prec = !isFinite(+prec) ? 0 : Math.abs(prec);
var sep = (typeof thousands_sep == "undefined") ? ',' : thousands_sep;
var dec = (typeof dec_point == "undefined") ? '.' : dec_point;
var s = (prec > 0) ? n.toFixed(prec) : Math.round(n).toFixed(prec); //fix for IE parseFloat(0.55).toFixed(0) = 0;
var abs = Math.abs(n).toFixed(prec);
var _, i;
if (abs >= 1000) {
_ = abs.split(/\D/);
i = _[0].length % 3 || 3;
_[0] = s.slice(0,i + (n < 0)) +
_[0].slice(i).replace(/(\d{3})/g, sep+'$1');
s = _.join(dec);
} else {
s = s.replace('.', dec);
}
return s;
}
function buildXmlHttp()
{
var xmlHttp;
try
{
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Your browser does not support AJAX!");
return false;
}
}
}
return xmlHttp;
}
function ajaxValidation(form, page)
{
try
{
var el = form.elements.length;
}
catch (err)
{
form = this;
}
var xmlHttp = buildXmlHttp();
var url = 'index.php?option=com_rsform&task=ajaxValidate';
if (page)
url += '&page=' + page;
var params = new Array();
var submits = new Array();
var success = false;
var formId = 0;
for (i=0; i<form.elements.length; i++)
{
// don't send an empty value
if (!form.elements[i].name) continue;
if (form.elements[i].name.length == 0) continue;
// check if the checkbox is checked
if (form.elements[i].type == 'checkbox' && form.elements[i].checked == false) continue;
// check if the radio is selected
if (form.elements[i].type == 'radio' && form.elements[i].checked == false) continue;
if (form.elements[i].type == 'submit')
{
submits.push(form.elements[i]);
form.elements[i].disabled = true;
}
// check if form is a dropdown with multiple selections
if (form.elements[i].type == 'select-multiple')
{
for (var j=0; j<form.elements[i].options.length; j++)
if (form.elements[i].options[j].selected)
params.push(form.elements[i].name + '=' + encodeURIComponent(form.elements[i].options[j].value));
continue;
}
if (form.elements[i].name == 'form[formId]')
formId = form.elements[i].value;
params.push(form.elements[i].name + '=' + encodeURIComponent(form.elements[i].value));
}
params = params.join('&');
xmlHttp.open("POST", url, false);
//Send the proper header information along with the request
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", params.length);
xmlHttp.setRequestHeader("Connection", "close");
xmlHttp.send(params);
var success = true;
if (xmlHttp.responseText.indexOf("\n") != -1)
{
var response = xmlHttp.responseText.split("\n");
// All spans set to no error
var ids = response[0].split(',');
for (var i=0; i<ids.length; i++)
if (!isNaN(parseInt(ids[i])) && document.getElementById('component'+ids[i]))
document.getElementById('component'+ids[i]).className = 'formNoError';
// Show errors
var ids = response[1].split(',');
for (var i=0; i<ids.length; i++)
if (!isNaN(parseInt(ids[i])) && document.getElementById('component'+ids[i]))
{
document.getElementById('component'+ids[i]).className = 'formError';
success = false;
}
if (response.length == 4)
{
page = parseInt(response[2]) - 1;
totalPages = parseInt(response[3]);
rsfp_changePage(formId, page, totalPages, false);
}
for (var i=0; i<submits.length; i++)
submits[i].disabled = false;
}
if (success == false && document.getElementById('rsform_error_' + formId))
{
try {
document.getElementById('rsform_error_' + formId).style.display = '';
}
catch (err) { }
}
return success;
}
function rsfp_addEvent(obj, evType, fn){
if (obj.addEventListener){
obj.addEventListener(evType, fn, false);
return true;
} else if (obj.attachEvent){
var r = obj.attachEvent("on"+evType, fn);
return r;
} else {
return false;
}
}
function rsfp_getForm(formId)
{
var formIds = document.getElementsByName('form[formId]');
for (var i=0; i<formIds.length; i++)
{
if (parseInt(formIds[i].value) != parseInt(formId))
continue;
var form = formIds[i].parentNode;
if (form.tagName == 'FORM' || form.nodeName == 'FORM')
return form;
while (form.parentNode)
{
form = form.parentNode;
if (form.tagName == 'FORM' || form.nodeName == 'FORM')
return form;
}
}
}
Thanks #JuanMendes, it didn't help unfortunately. I made some reaserch to find out how could I modify the codes to send an asynchronous request but I didn't succeed. In the ajaxValidation fonction, there is
xmlHttp.open("POST", url, false);
if I change it to
xmlHttp.open("POST", url, true);
it should then be an asynchronous request, isn't it.
When I tested it, it didn't freeze the browser, however it doesn't show the error if fields are not filled up on the form. Instead, it validates which is not mean to be. Any help ?
As IAbstractDownvoteFactory mentioned, you're probably calling ajax in synchronous mode, which means exactly that, freeze the screen while you're waiting for the network call.
The reason it looks that way is that your ajaxValidation is returning a value. Typically, you would send an asynchronous request and your ajaxValidation would take a callback. Then the UI won't hang waiting for the XHR.
// This is an improvement over what you had
// Still poor code, since it's hard to tell what the function is doing
function rsfp_changePage(formId, page, totalPages, validate)
{
var form = rsfp_getForm(formId);
if (validate) {
// Change your AJAX validation function to take a callback, which passes the return
// value (asynchronous) instead of relying on a return value (synchronous)
ajaxValidation(form, page, function(validationResult){
if (validationResult) {
showProgress();
}
});
} else {
showProgress();
}
function showProgress() {
for (var i=0; i<=totalPages; i++) {
var thePage = document.getElementById('rsform_' + formId + '_page_' + i);
if (thePage) {
thePage .style.display = 'none';
}
var thePage = document.getElementById('rsform_' + formId + '_page_' + page);
if (thePage) {
thePage.style.display = '';
// Don't use eval, use window and bracket to avoid it
var func = window["rsfp_showProgress_" + formId];
if (typeof func == "function") {
func(page);
}
}
}
}
}