Internet Explorer render issue (simple JS timer - window.setTimeout) - javascript

<script language="JavaScript" type="text/javascript">
var theBar = createProgressBar(document.getElementById('progress-bar'));
var value;
function resetValue() {
value = 0;
}
function showProgress() {
value += 1;
theBar.setValue(value);
if (value < 100) {
window.setTimeout(showProgress, 100);
}
}
window.onload=resetValue();showProgress();
</script>
--
<script language="JavaScript" type="text/javascript">
function createProgressBar(elem) {
var div1 = document.createElement('DIV');
div1.className = 'progress-bar-background';
div1.style.height = elem.offsetHeight + 'px';
elem.appendChild(div1);
var div2 = document.createElement('DIV');
div2.className = 'progress-bar-complete';
div2.style.height = elem.offsetHeight + 'px';
div2.style.top = '-' + elem.offsetHeight + 'px';
elem.appendChild(div2);
return {
div1 : div1,
div2 : div2,
setValue : function(v) {
this.div2.style.width = v + '%';
}
}
}
</script>
--
div.field input{
height: 45px;
width: 270px;
font-size: 24px;
}
.progress-bar-background {
background-color: #D0D0D0;
width: 100%;
position: relative;
overflow:hidden;
top: 0;
left: 0;
}
.progress-bar-complete {
background-color: green;
width: 50%;
position: relative;
overflow:hidden;
top: -12px;
left: 0;
}
#progress-bar {
width: auto;
height: 10px;;
overflow:hidden;
border: 0px black solid;
}
--
This snippet works perfectly under Chromer, Safari and FireFox.
The only issue is with Internet Explorer.
It seems to render as "half-full" and doesn`t execute anything.
Since I`m not that familiar with JS I have no clue what to start looking for.
Would appreciate some noob friendly advice.

change this...
window.onload=resetValue();showProgress();
to this...
window.onload = function() {
createProgressBar();
resetValue();
showProgress();
};
and you should be fine.
Remember...
"window.onload" is a property of the Window object ... and the value of this property should be a function that will execute automatically once the browser has loaded the entire DOM AND all the content (images, css, js, etc.)
This a NOT a good place to execute your stuff however -- you should use the event "onContentLoaded" but since it is not uniformly supported across browsers -- you should use a JavaScript library such as jQuery or Prototype or MooTools instead.
BUT -- of course if you're new to JS -- do NOT skim over it in order to get the pleasure of using these libs -- first get the real taste of what JavaScript is and what it is like to juggle with the browser incompatibilities -- only then you'll be able to appreciate the full potential of these libraries.

The first thing I see is that you shouldn't create the progress bar (or reference anything in the DOM) until the page has been loaded. IE is particularly sensitive to this. It looks to me like you're calling createProgressBar right when the javascript is loaded rather than after the page is loaded.
When I put your stuff into a jsFiddle and make sure that the code doesn't run until the page is loaded, it works for me in IE8.
See it here: http://jsfiddle.net/jfriend00/CQqat/

Related

Why does website cause most elements to be recalculated upon small change after being hosted?

I decided to make a Pac-Man game and after I did it and everything was working somewhat fine on local document I pushed my website on Github pages and decrease in fps was enormous. It turned out page was making recalculation for hundreds elements which caused 20ms+ delay.
Here's a small part of the code that still has performance difference between local and github-pages hosted website.
const gameBoard = document.getElementById("game-board");
const root = document.documentElement.style;
let elements;
let characterNode;
let position = 658;
makeLevel();
function makeLevel() {
for (let i = 0; i < 868; i++) {
const element = document.createElement("DIV");
element.style.backgroundPosition = `0 0`;
let character = document.createElement("DIV");
character.className = "yellow";
element.append(character);
gameBoard.append(element);
}
elements = Array.from(gameBoard.children);
characterNode = elements[658].children[0];
changePosition();
}
function changePosition() {
root.setProperty(`--yellow-sprite-y`, `-32px`);
characterNode.style.transform = `translateX(-20px)`;
setTimeout(() => {
characterNode.style.transform = "";
characterNode.classList.remove(`yellow-visible`);
position = position - 1;
characterNode = elements[position].children[0];
characterNode.classList.add(`yellow-visible`);
changePosition()
}, 200)
}
:root {
--yellow-sprite-y: -32px;
}
#game-board {
width: 560px;
height: 620px;
display: grid;
grid-template-columns: repeat(28, 20px);
background-color: #000000;
}
#game-board > * {
position: relative;
width: 20px;
height: 20px;
}
.yellow {
position: absolute;
top: -4px;
left: -5.5px;
width: 30px;
height: 28px;
z-index: 10;
}
.yellow-visible {
background-image: url("https://i.imgur.com/SphNpH6.png");
background-position: -32px var(--yellow-sprite-y);
transition: transform 200ms linear;
}
<div id="game-board">
</div>
The exact problem in this code is line 29 which on local document performs like this:
while after hosting it on Github performs this way:
Why is it working this way and what can I do to lessen the performance decrease on hosted page?
Amazingly everything works well and bug doesn't exist on CodePen, yet on Github it still persists.
After getting some feedback that my site works well for other users I shared it on CodePen and it also worked fine, day later somebody said there could be an extension that could do something like that and indeed Adblocker Ultimate caused the slow performance.

Check if the x element is in complete view or not in the web page

I been trying to create a script that lets the user know if the #x element is in complete view or not so I have an if else conditional statement, which determines that.
The if condition is triggered in this situation
If the #x element can be seen completely in the web page.
The else condition is triggered in the following situations.
The #x element can not be seen at all or portions of the #x element can be seen.
Situation 1:
The window is small enough that the #x element is not seen any more or
the #x element is in incomplete view.
Situation 2:
CSS positioning is used to have the #x element not see able or incompletely in view in the web page.
Situation 3:
The #x element is so big for the web page to see completely that a portion of it is shown regardless if there is a scroll bar or not.
So even if the #x element is a pixel off in view then the else condition is still triggered as well.
Situation 4:
Other elements push the #x element out of sight or the #x element is pushed just enough where only a portion of the #x element can be seen in the web page.
Heads up
So how can I do this? I made many attempts to try to figure this out on my own but no luck yet so please provide a code example with my code in pure JavaScript only and please no jQuery examples or links to articles or other posts. I asked similar questions like this before in the past and no luck still. I just been
frustrated on the responses that I had been getting and now I question if this is even possible to do. I’m not asking any of you guys to do the code for me, all I’m asking if any of you guys can provide a code example with my code on how this can be done because I learned best that way just a heads up.
My current code now
/*
????
if(???){
var status='You can see #x completely in the web page.';
}
else{
var status='You can not see #x completely in the web page.';
}
document.querySelector('#status-output').innerHTML= status;
*/
html{
background-color: dodgerblue;
}
#x{
position: absolute;
top: -5px; /*<-- This should trigger the else condition because this makes the element not completely in view on the web page.*/
left: 15px;
background-color: lime;
height: 150px;
width: 150px;
border: 3px solid black;
}
#status-output{
position: absolute;
top: 150px;
}
<div id='x'></div>
<p id='status-output'></p>
I have made this exmaple base on your code. The checkSeen function is what you need for checking if element can be seen base on its position. I have also add an interval to move the <div> around so that you can see the status update base on the <div> position. Hope this help.
function checkSeen(id){
var x = document.getElementById(id);
if(x.offsetTop < 0 ) return false;
if(x.offsetLeft < 0 ) return false;
if(x.offsetTop + x.offsetHeight > window.innerHeight) return false;
if(x.offsetLeft + x.offsetWidth > window.innerWidth) return false;
return true;
}
function updateStatus(seen){
if(seen){
var status='You can see #x completely in the web page.';
}else{
var status='You can not see #x completely in the web page.';
}
document.querySelector('#status-output').innerHTML= status;
}
updateStatus(checkSeen("x"));
var testMovingInterval = setInterval(function(){
var x = document.getElementById("x");
if(x.offsetTop - window.innerHeight > 100){
x.style.top = "-100px";
}else{
x.style.top = (x.offsetTop + 1) + "px";
}
updateStatus(checkSeen("x"));
}, 10);
html{
background-color: dodgerblue;
}
#x{
position: absolute;
top: -5px; /*<-- This should trigger the else condition because this makes the element not completely in view on the web page.*/
left: 15px;
background-color: lime;
height: 150px;
width: 150px;
border: 3px solid black;
}
#status-output{
position: absolute;
top: 150px;
}
<div id='x'></div>
<p id='status-output'></p>
Something like:
const winTop = window.pageYOffset || document.documentElement.scrollTop;
const winLeft = window.pageXOffset || document.documentElement.scrollLeft;
const winWidth = window.innerWidth || document.documentElement.clientWidth;
const winHeight = window.innerHeight || document.documentElement.clientHeight;
const xElem = document.getElementById('x').getBoundingClientRect();
const doesFit = xElem.top >= winTop &&
xElem.left >= winLeft &&
xElem.top + xElem.height <= winHeight &&
xElem.left + xElem.width <= winWidth;
const status = `You ${doesFit ? 'can' : 'can not'} see #x completely in the web page.`;

Delay or specified width on body needed for correct rendering

(This is a follow-up on my previous question if anybody is interested in the background story for entertainment purposes. It will probably not help you understand this question.)
Here are two elements <aside> and <main> who have got their width and height via JavaScript so that their combined width is the width of your screen (note that their display is inline-block). If you run this code in your web browser (a maximized browser so that the width of your browser equals the width of your screen) you might note that the body surprisingly does not properly fit the elements:
<!DOCTYPE html>
<html>
<body>
<aside></aside><!-- comment to remove inline-block whitespace
--><main></main>
<script>
var h = screen.height/100;
var w = screen.width/100;
var e = document.getElementsByTagName("aside")[0].style;
e.display = "inline-block";
e.backgroundColor = "lightblue";
e.width = 14*w + "px";
e.height = 69*h + "px";
e.marginRight = 0.5*w + "px";
e = document.getElementsByTagName("main")[0].style;
e.display = "inline-block";
e.backgroundColor = "green";
e.width = 85.5*w + "px";
e.height = 69*h + "px";
e = document.getElementsByTagName("body")[0].style;
e.margin = e.padding = "0";
e.backgroundColor = "black";
</script>
</body>
</html>
If you however give the JavaScript a delay, the elements are rendered properly. This suggests that the body somehow "needs time" to figure out its correct width:
<script>
setTimeout(function() {
[...]
}, 200);
</script>
It is also possible to give the body the specified width of screen.width instead of introducing the delay, by adding the following line. This supports the previous guess that the body does not immediately know its correct width (unless specified):
<script>
[...]
e.width = 100*w + "px";
</script>
Even though I have taken the freedom to throw wild guesses to explain this, I do not actually have a clue to what is going on.
Why are the elements not placed properly in the first place, and why do these two solutions work?
(Note: It is also possible to fix this by setting the whitespace of the body to nowrap with e.whiteSpace = "nowrap";, but I suspect this does not do the same thing as the other two. Instead of creating space for the elements inside the body, this simply forces the elements to be next to each other even though there is not enough room in the body.)
You should wait for the DOM to be available before running your code, see here: pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it. That is possibly why setTimeout works. Also you should assign seperate variable names for your different elements.
// self executing function before closing body tag
(function() {
// your code here
// the DOM will be available here
})();
Is there a reason you are using Javascript and not CSS to accomplish this task? I suggest giving your elements css ids ie id="aside", then set your css styles:
html,body {
width: 100%;
height: 100%;
}
#aside {
display:inline-block;
position: relative;
float: left;
width: 14%;
height: 69%;
background: blue;
}
#main {
display:inline-block;
position: relative;
float: left;
width: 86%;
height: 31%;
background: azure;
}

Images display as broken Javascript

I'm testing out a script found here
Show images one after one after some interval of time
I don't get any errors, and it rotates the images but the images simply appear as little broken squares, which I'm assuming is the broken image icon.
I'm using google chrome, and on MAC, running mavericks. Also, all the files are on a user.local(server/host) page I created, so if I go into the directory structure in my browser, and I click on the images the images show just fine. It is only when I try to load the .html file that they appear broken. I've also tried loading images with PHP and I get the same broken image icon.
This is what I mean when I say all the files are my local computer as a server/host:
Anyone know why this is happening and how to fix it?
This is the script I'm using:
var current = 0;
var rotator_obj = null;
var images_array = new Array();
images_array[0] = "rotator_1";
images_array[1] = "rotator_2";
images_array[2] = "rotator_3";
var rotate_them = setInterval(function(){rotating()},4000);
function rotating(){
rotator_obj = document.getElementById(images_array[current]);
if(current != 0) {
var rotator_obj_pass = document.getElementById(images_array[current-1]);
rotator_obj_pass.style.left = "-320px";
}
else {
rotator_obj.style.left = "-320px";
}
var slideit = setInterval(function(){change_position(rotator_obj)},30);
current++;
if (current == images_array.length+1) {
var rotator_obj_passed = document.getElementById(images_array[current-2]);
rotator_obj_passed.style.left = "-320px";
current = 0;
rotating();
}
}
function change_position(rotator_obj, type) {
var intleft = parseInt(rotator_obj.style.left);
if (intleft != 0) {
rotator_obj.style.left = intleft + 32 + "px";
}
else if (intleft == 0) {
clearInterval(slideit);
}
}
</script>
<style>
#rotate_outer {
position: absolute;
top: 50%;
left: 50%;
width: 320px;
height: 240px;
margin-top: -120px;
margin-left: -160px;
overflow: hidden;
}
#rotate_outer img {
position: absolute;
top: 0px;
left: 0px;
}
</style>
<html>
<head>
</head>
<body onload="rotating();">
<div id="rotate_outer">
<img src="images/owl.png" id="rotator_1" style="left: -320px;" />
<img src="images/bee.png" id="rotator_2" style="left: -320px;" />
<img src="images/owl.png" id="rotator_3" style="left: -320px;" />
</div>
</body>
</html>
This sounds like a bad url in the src attribute of the image. right click the broken image icon and inspect it (most, if not all browsers support this) and see where the url leads.
Fixing url, try one of the following:
Try adding a / in front of your image links
Try including the full path on the image including the http, also you can try excluding the http and writing //yourwebsite.com/images/foo.jpg instead and see if that fixes things.
If you work on some framework there is bound to be a base url variable which you can use instead of manually writing the url

Background not appearing with customized pseudo-popup

I'm having a problem with the background of a pseudo-popup. I use jQuery (1.7) and this tutorial to create popups in my website. Basically I have two preformatted divs (one semi-opaque to hide the rest of the page and the other - with an image as the background - containing the actual popup, with the CSS already loaded in the page) that aren't displayed and that I show when I need them to display the popup, with additional fillings for the second div (to have different popups).
My problem is that the background of the popup doesn't load, and that I end up with only the semi-opaque background and the content of the popup. However, if disable/enable the CSS background property in the console, the background reappears as it should have in the first place.
This problem has appeared relatively recently not after any modification to the actual popup function, so I don't really know where it might come from. It can't be an issue of the background image not yet loaded since it is already there when the page has loaded.
Relevant pieces of code:
HTML:
<div id='popup_container'></div>
<div id='backgroundPopup'></div>
CSS:
#backgroundPopup{
display:none;
position: fixed;
_position:absolute; /* hack for internet explorer 6*/
height: 100%;
width: 100%;
top: 0;
left: 0;
background: #000000;
border: 1px solid #cecece;
z-index: 1;
}
#popup_container{
display: none;
position: fixed;
_position:absolute; /* hack for internet explorer 6*/
height: 526px;
width: 718px;
background: url(http://cdn.mojogroups.com/Layout/popup.png) no-repeat !important;
z-index: 2;
color: #000000;
}
Javascript:
//When initializing the page
$(document).ready(function(){
//[...]
popup = new Popup();
popup.initialize();
}
function Popup(){
var popupStatus = 0;
function togglePopup(){
if(popupStatus == 0){
centerPopup();
loadPopup();
}
else
disablePopup();
}
function loadPopup(){
if(popupStatus == 0){
$('#backgroundPopup').css({
"opacity": "0.7"
});
$('#backgroundPopup').fadeIn("fast");
$('#popup_container').fadeIn("fast");
$('body').scrollTop(0);
$('body').css('overflow', 'hidden');
popupStatus = 1;
}
}
this.disablePopup = function(){
if(popupStatus == 1){
$('#backgroundPopup').fadeOut("fast");
$('#popup_container').fadeOut("fast");
$('#popup_container').empty();
$('body').css('overflow', 'auto');
popupStatus = 0;
}
}
function centerPopup(){
var windowWidth = document.documentElement.clientWidth;
var windowHeight = document.documentElement.clientHeight;
var popupHeight = $('#popup_container').height();
var popupWidth = $('#popup_container').width();
$('#popup_container').css({
"position": "absolute",
"top": windowHeight/2 - popupHeight/2,
"left": windowWidth/2 - popupWidth/2
});
$('#backgroundPopup').css({
"height": windowHeight
});
}
this.initialize = function(){
$('#backgroundPopup').click(function(){
popup.disablePopup();
});
$(document).keypress(function(e){
if(e.keyCode==27)
popup.disablePopup();
});
}
this.contacts = function(){
//Fill the popup container...
centerPopup();
loadPopup();
popupDiv.fadeIn('fast');
}
What could it be?
Thanks in advance for your help!
EDIT: the site (early version) can be found here
UPDATE: At some point I thought it was due to the opacity attribute added by the loadPopup() function, so I removed that part of the code; but the bug still appears (although maybe less frequently, but it's hard to be sure since it was transient in the first place).
I know its not the ways to as query in answer but i we cant add images in comments so i m asking here. I have just gone through with your problem, what i m getting is you cann see the below screen shot. Is it correct output or not.

Categories