I have installed a script on my website that allows for a low contrast setting and a high contrast setting, as my site will be used by sight impaired persons. The script works perfectly. The only problem is when a visitor visits multiple pages of the site.
When you first visit the site, the low contrast setting is in effect by default and only the link to the high contrast setting appears. If you then visit other pages of the website, the low contrast setting is in effect by default and only the high contrast link appears (this is perfect and as it should be). The website does this by using a cookie.
Here is the problem. If you click on the high contrast link to view the page in the high contrast setting and then go to another page, the other page appears in the high contrast setting (as it should), but instead of a link to the low contrast setting appearing (which I would like to happen), a link to the high contrast setting appears (which does not make sense, given the page is already in the high contrast setting).
My site is not done, but I published a few pages at http://www.14kt.eu/ so you can see what I am talking about. A number of the members of this site were kind enough to help me with the code/script and things were working perfectly for a bit, but then it just stopped working. I suspect I changed something in the rest of the html that caused this. Rather perplexed over this issue.
If anybody can please tell me how to fix this problem, I would be most grateful.
Thank you for your time, Chris
It looks like you just need your stylesheet buttons to be conditionally hidden based on the cookie.
You can do this with the code below (updated):
function setStylesheetFromCookie() {
var stylesheet = readCookie('mysheet') || 'none';
if( stylesheet == 'highcontrast' ) {
console.log('high');
document.getElementById('Lc').style.display = 'block';
document.getElementById('Hc').style.display = 'none';
} else {
console.log('low');
document.getElementById('Hc').style.display = 'block';
document.getElementById('Lc').style.display = 'none';
}
}
Add that code somewhere in script_1.js.
In order for that to work, it needs to run on window load.
This brings us to problem two. You have two different window.onload assignments in script 1.
You need to consolidate the two. Delete the line
window.onload = FixRows;
And modify the second window.onload = function() to look like the following:
window.onload = function() {
var el = document.getElementById('mydiv');
var size = readCookie('fontsize');
if(size) {
doChangeSize(el, size);
}
var original = readCookie('originalsize');
if(original) {
el.originalSize = original;
}
FixRows(); //You are adding this line
setStylesheetFromCookie(); //and adding this line to the end of the function
}
Notice the two new function calls at the end.
This should solve your problem.
Cheers!
Just kind of poking around and it appears as though you've got javascript running in a couple different directions at the same time. window.onload is tied separately to two different functions. The first one calls FixRows which should work to display 'low contrast'/'high contrast' appropriately (from the cookie you set). I'm thinking the second window.onload is overriding the first.
I don't think this is directly affecting your code, but you have setCookie() in styleswitcher.js and createCookie() in script_1.js - they are doing the same thing. I'd say you should at least consolidate you cookie functions in one or the other library to cut down on confusion.
Hope I've been helpful.
Related
I am creating a chrome extension that adds a button to the youtube player HUD (to the left of the watch later button). This works fine, but the only problem is that when the HUD autofades after a few seconds of inactivity, this button element doesn't.
I've added the button to the following div using javascript:
<div class="ytp-chrome-top-buttons"> </div>
and my button looks like this:
<button class="customClass" id="customID" title="custom title"><svg class="customClass"></svg></button>
I've looked through the source of the page to try and see how exactly youtube makes the other icons disappear, and whether I can copy a class to my svg to make it disappear, but I haven't been able to find it.
I've looked at using a timer and javascript to make the element disappear, but I figured if the functionality is already there, why complicate it.
As a last resort I will be resorting to using the timer method, but I'd much prefer using CSS classes.
I have had a cursory glance into the Youtube Player API, but to be frank, I'm having a hard time understanding how it works (While I have a few years of programming experience, I only started learning javascript, HTML, and CSS yesterday). I also understand that this API is only for embedded youtube videos?
To clarify, I DO know how to use API's in javascript, just not this particular one. I have used the youtube data API to implement the button's functionality successfully.
Any help is appreciated.
Thanks.
If you examine the element changes, you can see that the class list of the video has changed with the change of the bottom bar. When the bottom bar is hidden, the ytp-autohide class is added. Keeping this in mind, after scanning the class changes with the mutation observer, you will reach the desired result when the ytp-autohide class's existence status changes.
var video = document.querySelector("#movie_player");
var lastState = video.classList.contains('ytp-autohide');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if(mutation.attributeName == "class"){
var currentState = mutation.target.classList.contains('ytp-autohide');
if(lastState !== currentState) {
lastState = currentState;
if(currentState)
console.log("Hided");
else
console.log("Shown");
}
}
});
});
observer.observe(video, {attributes: true});
I have a web site containing millions of photos from thousands of events over the last 26 years, and the directory structure is \root\events\(year)\(eventdate) so that all the photos and files for any given event date are kept together. Each directory has its own index.shtml file which sorts out the organisation of the content.
I want to add a mobile version of the site. My current thinking is to add a mobile.shtml page to each directory, and switch based on a simple screen width test. All the pages throughout the site use a common header include, so I need to add code to a common header, but which will only switch if the current page is the index.shtml file. I´ve used the following, and it fails to switch.
This is what I´ve added to the include file
......
<body>
<script>
var url = location.href;
var filename = url.substring(url.lastIndexOf('/')+1);
var a = "index.shtml";
if((screen.width < 600) && (filename.equals(a))) {
location.href = 'mobile.shtml';
}
</script>
.........
I´m not a JS programmer and am trying to implement code seen hereabouts, so would appreciate learning why this fails! Thanks in advance to anyone that replies.
I have not used this for a while but I am pretty sure it still works. Place this in the Head of your HTML e.g. desktop website - index.html
<!-- Detect and redirect for mobile -->
<script type="text/javascript">
if(navigator.userAgent.match(/iP(od|hone)/i) || navigator.userAgent.match(/Android/i)){
if(document.cookie.indexOf("iphone_redirect=false")==-1) {
window.location.href="http://myWebsite.com/index_mobile.html";
}
}
</script>
Be sure to add your correct redirect here in this line from above:
window.location.href="http://myWebsite.com/index_mobile.html";
As a second solution to support your original intentions, I managed to get a variation of your JS code working live here DEMO. My DEMO will take you to GitHub if you view it from a screen with a width < or = to 600px. To test it properly you must view it from monitor sizes above and below 600px widths. Below is my variation of your JS code:
<body>
<script>
var url = window.location.href;
var filename = url.substring(url.lastIndexOf('/')+1);
var a = 'index.shtml';
if((screen.width <= 600) && (filename == a)) {
window.location.href = 'https://github.com/';
}
</script>
* NOTE the difference that my code will redirect you to GitHub as opposed to 'mobile.shtml'
What you are trying to accomplish should be done with responsive design techniques. In a perfect world, you could just use media queries
to adjust the css applied to format the content differently.
But I have also had the need sometimes to do server side detection of the client, because I would render an entirely different widget based on the form factor. You seem to be using .shtml, which is a poor choice IMHO. Your webserver at a min must support php, and that is a way more powerful server side choice for your app. PhpMobileDetect is a great script that will give you a way to detect if it is mobile, tablet, or desk. Problem now is that we have enormous phones, or phablets. But it might just be the right fit for your task.
I've been trying to solve this for several time, but I'm now pointless with this situation. I'm creating a HTML5 canvas project in Flash CC, I'm kinda new in JS (not difficult BTW), the point is, I have around 10 keyframes inside my main timeline, and some classic buttons, all I need to do is to navigate inside every frame when a button is pressed (pretty easy uh!) the trouble is, the first frame works perfectly, but from 2 to the others, I can't be able to use buttons, interactivity is being programmed as follows:
var self = this;
this.stop();
this.btn4.addEventListener("click", clickUno);
function clickUno() {
self.gotoAndPlay(1);
}
Any help will be really appreciated, I just don't know why 1st frame works great, but others doesn't!
I had similar issues with canvas with flash.
I needed to created completed new buttons on every instance you need a button to get code to work. (ODD I know.)
Button code.
this.getinsideIt.addEventListener("click", fl_ClickToGoToAndPlayFromFrame_9.bind(this));
function fl_ClickToGoToAndPlayFromFrame_9()
{
this.Mygreatmovie.gotoAndPlay(350);
}
As I understand, you need a button, clicking on which proceeds your animation 1 frame at a time. Correct?
You should make use of the currentFrame and totalFrames properties of the main stage for this. Query the current frame and move on to next!
var self = this;
this.stop();
if(!this.btn4.hasEventListener("click", clickUno))
this.btn4.addEventListener("click", clickUno);
function clickUno(e) {
var curr = self.currentFrame;
var total = self.totalFrames;
self.gotoAndStop((curr + 1)%total);
}
We are trying to build an HTML game in which abobe edge is being used for animations and those animations are being inserted into iframes. We are trying to preload the iframes before removing the 'loading screen' so that the users won't see blank iframes initially.
Here is the code for loading the iframes.
We have a global variable var middleBotLoaded = false;
The following function tries to dynamically populate the iframe and once the iframe has loaded , we are assigning the variable to true
function _trackIFrameLoading()
{
if (document.getElementById("botzmiddleidlesequence_iframe").attachEvent)
{
document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { middleBotLoaded = true; });
}
else
{
document.getElementById("botzmiddleidlesequence_iframe").onload = function() { middleBotLoaded = true; };
}
document.getElementById("botzmiddleidlesequence_iframe").src = APP_BASE_URL + "blitzbotzidlesequence/blitzbotz/"+middleBotzId;
}
We have a method to check if the global variable has become true and if so , we are removing the loading screen.The method is being called in a interval of 500 milliseconds
setTimeout(_haveAllCharactersLoaded,500);
function _haveAllCharactersLoaded()
{
if(middleBotLoaded == true)
{
$(jOverlay).fadeOut(800, function() {
$(jOverlay).remove();
});
}
else
{
setTimeout(_haveAllCharactersLoaded,500);
}
}
The problem is that even after the loading screen disappears , the iframe contents take time to come up on the screen .
We have observed that the duration depends on the speed of the net connection , but then , isn't using onload the whole point of making sure that the contents have loaded.
Is there any other approach for dealing with this problem.
Thanks.
EDIT : I have to wait for two days before I can start a bounty but I am willing to award it to anyone who can provide a canonical answer to the question.
I have two answers here.
First, I think you should reconsider the way you're coding this game, unless it's a static, turn based game that only relies upon animations (think Pokemon.)
Second, I have a suggestion for you to try in fixing your code.
First Answer:
You asked if there is any other approach to dealing with this problem.
My first reaction to that, would be to skip using iFrames entirely. Adobe Edge may provide you with a good way to craft animations, but for use in a game engine you will only find yourself fighting against the design of how Adobe Edge handles it's animations.
Instead, I would recommend learning how to use HTML5's canvas element. Canvas is built to handle dynamically loaded content (such as your game engine will be generating.) I can only imagine the event of having particle effect animation overlayed onto a game character as he is hit by a weapon. With your current approach, would you place that in an iFrame? Then, how would you ensure that this particle effect is placed on the correct location on the object?
There are many resources out there to help you begin learning the code you need to make a true game engine in the browser. I would recommend beginning by learning how Canvas works. If you want to animate using the DOM, learn about requestAnimationFrame.
http://creativejs.com/
http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial
Second Answer:
I would recommend looking into the variable scope of your middleBotLoaded. This answer (Set variable in parent window from iframe) would be a good place to look.
Instead of using document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { middleBotLoaded = true; });
try using document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { parent.middleBotLoaded = true; });
Alternatively, try something along these lines:
onLoad event:
document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { parent.middleBotLoaded();});
Function to handle loading:
function middleBotLoaded()
{
$(jOverlay).fadeOut(800, function() {
$(jOverlay).remove();
});
}
It's a better practice to directly call an event, rather than polling for variable changes using setTimeout.
and thank you for taking a look at this question.
We have developed a website which has a navigation control (Next and Previous buttons) written in Flash. These buttons use ExternalInterface to call a Javascript function in my webpage, e.g. ExternalInterface.call("showPage", pageNum);
My HTML page contains a number of Divs which each represent a single 'screen'. The first Div (screen) has the CSS Display set to 'inline' and all of the remaining are set to 'none'.
The Javascript showPage function which is called when the Flash button is clicked is as follows and it calls the hideShow function:
function showPage(which) {
if (pagetype == "lo"){
if(which < 0 && isRunningInFrame()){goPrev();}
else if (which > maxPageNum && isRunningInFrame()){goNext();}
else{dsPages.setCurrentRow(which);}
}
hideShow('page' + currentRow, 'page' + which);
prevRow = currentRow;
currentRow = which;
}
function hideShow(hideDiv, showDiv){
if(document.getElementById(hideDiv)!=null){
document.getElementById(hideDiv).className = "hideDiv clear";
}
if(document.getElementById(showDiv)!=null){
document.getElementById(showDiv).className = "showDiv clear";
}
}
This all works well in contemporary browsers and is very responsive. However our client has Internet Explorer 6 on all of their PCs (well they would wouldn't they!) and when you click Next the complete page reloads. I only assume this is happening because I can see in the bottom left corner of the browser (in the grey bar) all of the JPEG images loading. Some of the HTML pages contain approximately 50 'screens' and this is very slow when they all load over and over again.
I would be very grateful if anyone can see why this is happening or could suggest a more efficient approach to this.
Thank you.
Regards
Chris
Pointy may have a point here (no pun intended). A simple guess-suggestion would be to try placing a 'return false;' after your js-call.