Disabling interval function resulting in visual glitches - javascript

I have created a small piece of code that creates a DIV at a random 'fixed' location every 80ms. This div shows up for about 2seconds and then removes itself (including the code generated). However when leaving the part of the page where this is happening (using scrolling); I want the generator to stop.
And to avoid executing the code everytime the user uses his scroll (duplicate generators, because of scrolling) I thought it would be most useful to use a true/false statement.
if (focuson = true){window.setInterval(function(){$(generator);}, 80);}
$(window).scroll(function(){
if ($(window).scrollTop() > resolutieh){
var focuson = false;
window.clearInterval(generator); generator = 0;
}
else{
var focuson = true;
}
});
The code above actually works but results in a visual glitch; when the last generated DIV gets removed: every part of the screen at that moment, that is not 'filled' with div-content will be filled with big white chunks (basically the 'background-image' on repeat x/y). Also scrolling back to the location where the generator is active doesnt activate it again.
The following piece of code seems more logical to me (although it doesnt work):
if (focuson = true){window.setInterval(function(){$(generator);}, 80);}
if (focuson = false){window.clearInterval(function(){$(generator);}, 0);}
$(window).scroll(function(){
if ($(window).scrollTop() > resolutieh){
var focuson = false;;
}
else{
var focuson = true;
}
});
I basically want to avoid the visual glitch by either stopping the generator 'properly' or setting its timer so low that it takes less time to calculate. A cool bonus would be that if you would come back to the part of the page where the generator is spawning, it would turn on again.
Any suggestions?
Kind Regards.

Related

Image won't be resized in javascript when removing alerts

I have a database with image paths. through PHP, I insert the pictures on my website. The problem is that the code that I have won't work. So, I decided to put some alerts to figure out what is the issue. After going through the alerts, I noticed that the images were resized and repositioned. After some reading, I found out that this is because the javascript is executed in the same time as the HTML and CSS and the alert halts the javascript, letting the HTML and CSS to be executed. How should I change my code to make the images work? This is the code in question:
var box = document.getElementsByClassName("produs");
var pic = document.getElementsByClassName("imagine_produs");
var i;
for (i = 0; i < pic.length; i++) {
alert(pic[i].width);
if ( pic[i].width > 200 ) {
pic[i].width="200";
alert(pic[i].width);
}
var marg = (box[i].clientWidth - pic[i].clientWidth ) / 2;
pic[i].style.marginLeft = marg + "px";
pic[i].style.marginRight = marg + "px";
}
Also, I have made a photo album that is in order to show how the code executes:
What other way is there to either halt the code or to rearrange it so that it works like in the last picture?
THanks!
You might use
console.log()
instead of alert() for debugging purposes. That way you can monitor what your code is doing without interrupting it with prompts.
Apart from that, the funtionality of your code might better be realised with CSS eventually (i.e. margin:auto; img max-width:90%; …).

How to properly scroll IFrame to bottom in javascript

For a mockup-webpage used for research on interaction on websites, I created a mockup message-stream using JavaScript. This message stream is loaded in an IFrame and should show images at pre-set intervals and scroll to the bottom of the page after placing a new image at the bottom of the page. Getting the images to appear is working quite well with the provided script. However, both Chrome and IE seem to have trouble scrolling the page to the bottom. I would like to scroll to the bottom of the page as soon as the image is attached, but have for now added a 5 ms delay because that seemed to work sometimes. My questions are:
Is it okay to use document.body.scrollHeight for this purpose?
Can I make the scroll occur directly, or do I need a small interval before scrolling?
How to make the code scroll to the bottom of the IFrame directly after adding an image?
The following functions are used and trypost() is started onLoad:
function scrollToBottom(){
window.scrollBy(0,document.body.scrollHeight);
}
function trypost(){
point = point + 1;
if(point < interval.length){
//create and append a new image
var newImg = document.createElement("IMG");
newImg.src = "images/"+images[point]+".png";
document.getElementById('holder').appendChild(newImg);
//create and append a return
var br = document.createElement("br");
document.getElementById('holder').appendChild(br);
//time scroll to bottom (after an arbitrary 5 seconds)
var stb = window.setTimeout(scrollToBottom, 5);
//time next post
var nextupdate = interval[point]*400;
var tp = window.setTimeout(trypost, nextupdate);
}
}
My script section contains at least the following variables:
var point = -1;
var interval = [10, 10, 15];
var images = ["r1", "a1", "r2"];
This questions is a continuation of the project described in How to proper use setTimeout with IE?
To answer one of your questions, document.body.scrollHeight is appropriate for this purpose, but not if you're actually calling for document. That'll give you the scroll height of the document the iFrame is in, not the iFrame's document. The iFrame's document can be called upon by [insert variable for iFrame here].contentDocument.
Here's how I did it (and by that, I mean I tested it out with my own stuff to make sure it worked):
let i = document.querySelector('iframe')
i.contentWindow.scrollTo(0, i.contentDocument.body.scrollHeight);
That being said, the other answer by Thomas Urban will also work most of the time. The difference is only if your page has a really long scroll height. Most pages won't be longer than 999999 (for all I know that's impossible and that's why they chose that number), but if you have a page longer than that, the method I showed here would scroll to the bottom and the 999999 would scroll to somewhere not yet at the bottom.
Also note, if you have more than one iFrame, you're gonna want to query it in a different way than I did, like by ID.
Scrolling to bottom is always like scrolling to some ridiculously large top offset, e.g. 999999.
iframe.contentWindow.scrollTo( 0, 999999 );
In addition see this post: Scrolling an iframe with javascript?
If scrolling occurs too early it's probably due to images not being loaded yet. Thus, you will have to scroll as soon as added image has been loaded rather than on having placed it. Add
newImg.onload = function() { triggerScrolling(); };
after creating newImg, but before assigning property src.
If several events are required to trigger scrolling you might need to use some "event collector".
function getEventCollector( start, trigger ) {
return function() {
if ( --start == 0 ) { trigger(); )
};
}
You can then use it like this:
var collector = getEventCollector( 2, function() { triggerScrolling(); } );
newImg.onload = collector;
window.setTimeout( collector, 100 );
This way triggerScrolling() is invoked after 100ms at least and after image has been loaded for collector has to be invoked twice for triggerScrolling() being invoked eventually.

window.scrollTo not working in phonegap - alternative solution or workaround?

I've written a rather basic js function that programatically and automatically aligns the iPhone keyboard perfectly underneath each and every input field that gets focused (feel free to use it if you like it!). The alignment's primarily handled by window.scroll - a standard method that works in any browser view, except in UIWebView hence phonegap/cordova (2.1). So I need a workaround.
My working code:
function setKeyboardPos(tarId) {
//programmatically: set scroll pos so keyboard aligns perfectly underneath textfield
var elVerticalDistance = $("#"+tarId).offset()["top"]; //i.e. 287
var keyboardHeight = 158;
var heightOfView = document.height; // i.e. 444
var inputHeight = $("#"+tarId).outerHeight();
var viewPortSpace = heightOfView-keyboardHeight; //i.e. 180
var verticalNewSroll = (elVerticalDistance+inputHeight)-viewPortSpace;
if(verticalNewSroll<0) { verticalNewSroll = 0; }
////
//OK, all done lets go ahead with some actions
$("#footer").hide(); //hide footer so that the keyboard doesn't push it on top of textfield
$("#containingDiv").css("bottom","0px"); //remove bottom space for footer
window.scrollTo(0,verticalNewSroll); //scroll! where the problem starts
}
Working in everything but UIWebView, that is. As I mentioned above, everything works except the window.scrollTo (N.B. some minor changes have been made for the sake of clarity). So does anyone know of an alternative solution or even a good workaround?
Similar questions
window.scrollTo doesn't work in phonegap for IOS
PhoneGap / Cordova scrollTo Ignored
How to add vertical scroll in Phonegap
Above are furthermore three similar questions that somewhat points one in the right direction. One of the answerers mentions the use of css to accomplish this. Can anyone come up with a more concrete example? Another guy suggests anchors but that's not a very pretty solution and doesn't go very well with the rest of my code.
After doing some research, I realized window.scrollTo() does actually work in iOS6 with phonegap 2.1, there was something else that failed; for some reason, document.height didn't yield a property of equal proportion within UIwebView so I had to write a small workaround. I'll post the solution and the entire code below for future reference.
function setKeyboardPos(tarId) {
//programmatically: set scroll pos so keyboard aligns perfectly underneath textfield
var elVerticalDistance = $("#"+tarId).offset()["top"];
var keyboardHeight = 157;
if(isNativeApp()) { keyboardHeight = 261; } //I choose to change the keyboard height for the sake of simplicity. Obviously, this value does not correnspond to the actual height of the keyboard but it does the trick
var keyboardTextfieldPadding = 2;
var heightOfView = document.height;
var inputHeight = $("#"+tarId).outerHeight();
var viewPortSpace = heightOfView-keyboardHeight-keyboardTextfieldPadding; //180
var verticalNewSroll = (elVerticalDistance+inputHeight)-viewPortSpace;
if(verticalNewSroll<0) { verticalNewSroll = 0; }
////
//OK, all done lets go ahead with some actions
$("#footer").hide(); //hide footer so that the keyboard doesn't push it on top of textfield
$("#containingDiv").css("bottom","0px"); //remove bottom space for footer
window.scrollTo(0,verticalNewSroll); // perform scroll!
}
function isNativeApp() {
var app = (document.URL.indexOf('http://') === -1) && (document.URL.indexOf('https://') === -1);
if (app) {
return true; // PhoneGap native application
} else {
return false; // Web app / safari
}
}
you can try and use the animate and scrollTop property to scroll It looks something like this:
$("html, body").animate({ scrollTop: "The value to scroll to" });
Hope this helps.
You just need to use this:
$(window).scrollTop(0);

Scrolling Iframe

I have two windows: One is a page meant to be in an iframe, and one is the page meant to house the iframe. The objective of my project is to make an iframe that scrolls, but, when it is moused over, it pauses. I currently have the following code for the page meant to be in an iframe:
http://dabbler.org/edit/asdf/scrolling/index.html
and the code for the page meant to house the iframe:
http://dabbler.org/edit/asdf/scrolling/index2.html
What is wrong with my code? (Yes, I know I don't have body, head, HTML and the others, that isn't the problem, for those are thrust in automatically when the page is interpreted)
The window.onmouseover and window.onmouseout are not defined correctly.
You have this:
window.onmouseout = pageScroll();
window.onmouseover = unpageScroll();
You want to do this:
window.onmouseout = pageScroll;
window.onmouseover = unpageScroll;
You were setting onmouseout, and onmouseover to the return values of calling pageScroll and unpageScroll, but you wanted to set onmouseout/onmouseover the functions pageScroll and unpageScroll.
And finally, you're calling the wrong function in your setTimeout.
You are calling pageScroll, but you want to be calling pageScroller, which does the actual scrolling.
EDIT
function pageScroll(){
num = 150;
clearTimeout(scrolldelay);
pageScroller();
}
function unpageScroll(){num = 15000000;}
function pageScroller() {
window.scrollBy(0,50); // horizontal and vertical scroll increments
scrolldelay = setTimeout('pageScroller()',num); // scrolls every 100 millisecond
}
var num = 50;
window.onmouseout = pageScroll;
window.onmouseover = unpageScroll;
BTW, you should handle calling clearTimeout in pageScroller at some point in the future when the page is scrolled vertically as much as possible. There's no point in continuing to call scrollBy if the window is already scrolled as much as possible.

Javascript Show and Hide Divs Reloads Complete Page in IE6

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.

Categories

Resources