Wait to call a method from the Action page - javascript

I'm kinda new to the JSP world.
I have this web application that calls the page below, the result.jsp page.
This page is called after a submit on a form, and the action class generates an image from the createImage method, called by a dispatchParam.
The actual code part is this:
<div id="container_imagem_resultado">
<p>
<img src="<%=pathBase%>access.do?dispatchParam=createImage&time="new Date().getTime();>
</div>
I need to create some trigger so the page waits for 1s before calling the img tag.
How can I do it?
is there a way to dinamically insert into the HTML response page the tag after that 1s wait? Would adding <%Thread.sleep(1000);%> just before the img tag work?

Doing a delay in Java (server-side) on the page, even in a scriptlet, will only result in a delay in sending the page to the client's browser, which results in either a long pause before they receive the page, or (in some cases) a half-loaded page with an odd delay until the rest is loaded.
To delay the loading of something on the client-side, the best answer is to use Javascript. Given that you've tagged the question jquery, I'm going to assume that jQuery is an available option for you.
For that purpose, this answer gives a reasonable example of what to do here:
// jQuery construct; calls this function after the page is ready.
$(document).ready(function () {
// Create the function which loads the image.
function showImage() {
// Gets a handle for the container div, and replaces its HTML contents.
// Not the most elegant, but it works.
$("#container_imagem_resultado").html('<p><img src="<%=pathBase%>access.do?dispatchParam=createImage&time=' + new Date().getTime() + '" /></p>');
}
// Schedule it after 1 second (1000ms).
setTimeout(showImage, 1000);
});
And the HTML:
<div id="container_imagem_resultado">
<p>
<!-- TODO placeholder -->
</p>
</div>
As a side note, isn't 1 second a little long for a loading delay? Unless you intend for there to be a noticeable lag in the image loading, or there's another reason for loading the image after 1 second, you should make it a lot lower, otherwise it might come across as a broken window.

Related

Javascript From Console - Load a Few Pages, Then Run Function Per Page Load [duplicate]

I'd like to be able to call a jquery function once window.location has completed loading a URL. Is this possible? I can't seem to find anything online about this.
for instance:
if(parseInt(msg.status)==1) {
window.location=msg.txt;
alert("This URL has finished loading")
}
Thanks,
-Paul
You can either use window.onload of the destination page (if you have access to modify the code of that page), or you can use window.onunload to have the alert be launched when unloading the current page. You cannot execute code on the current page after the new page has been loaded.
Yes.
This page demonstrates onload/onunload behavior.
<html>
<head>
<script>
window.doUnload = function(){
alert("Here!");
}
window.doLoad = function(){
window.location="http://www.google.com";
}
</script>
</head>
<body onload="doLoad();" onunload="doUnload();"></body>
</html>
After a user logs in for the first time I need to load my index page to initialize everything but then need to forward them to another page for profile completion.
use window.location to redirect the user to your index, adding a query parameter (something like window.location=index.php?firstLogin=true ) and on your index redirect (using javascipt http 300, header() or whatever you are using) to the profile page after it ends loading if the parameter is set
Iframe
One (ugly) method you could use is to instead of using window.location, clearing the body, adding an iframe with the relevant path and listening to its onload function.
After that you can run code inside the iframe as long as it's not cross-site scripting.
I use this method to perform small automated scripts, that can't really on third-party plugins.
Ajax
Another method might be using ajax to load the page/body content. Then replacing your body with the newly loaded body and start executing the next functions.

Change html before rendering to avoid a flicker

I have code I'd like to run before the page is rendered. For example updating dates from absolute time to relative time or converting raw text (or markdown) to html. If I reload the page several times I can see occasionally there's flickering updating the changes. How do I run the code as it's drawn instead at the end where it needs to redraw everything?
I tried document.addEventListener('beforeload' it appears that event is depreciated and no longer supported in chrome
You'll need to think about your page lifecycle.
When your page is being loaded, if a <script> tag is encountered, it will immediately be executed, and prevent any more content being rendered until that script is complete. This isn't recommended practice.
But, to answer your question, you could do something like this:
<p>Your next reward will be available in <span id="nextRewardTime">3600</span>.</p>
<script type="text/javascript">
var $el = $('#nextRewardTime');
$el.text(format($el.text());
</script>
<p>Come back soon!</p>
Now, immediately after the first <p> is downloaded by the browser, it'll hit the <script> tag and execute the JS. Only once that is complete will it download the next <p> tag ('Come back soon!').
You can't attach an event handler to the Javascript before it's been rendered on the DOM, because... well... it's not on the DOM.
The better way of doing this is to format the thing correctly on the server in the first place.
Edit: Also, scattering script tags throughout your page makes your code really unmaintainable!
I would use document.readyState and a self-invoking function:
<body>
<script>
function executeFunction() {
//do stuff - such as check for anchor tags
$("a").html('Replaced');
if (document.readyState === 'loading') executeFunction(); // repeat to ensure all the tags get innerHTML-ed
}
(function(){
if (document.readyState === 'loading') executeFunction();
})();
</script>
<!-- more HTML -->
</body>
It seems that you want JS to execute as the page is loading. You may also want to try using uninitialized as the ready state (which occurs before "loading").

What to do if $(window).load(function(){}); is too early

I need to trigger a piece of code after every single bits are done downloading. The script works if injected after everything is loaded, but how do I trigger that automaticly?
My script is:
var divId = "jwplayer-0_wrapper";
if ($('#' + divId).length == 1) {
myReg = /https?:\/\/www\.youtube\.com\/watch\?v=[^"]+/;
var plainText = $('#' + divId).parent().children('script').text();
var url = plainText.match(myReg);
if (url !== null) {
window.location = url;
};
};
It is used to skip certain site that decide to use the JW player witch I find horribly buggy. So it looks for a div with the indication of the JW player and if there's one, it finds the link to the original youtube video and directly goes there.
Its triggered By Google Chrome Add-on named Javascript Injector and I apply the script on every page I visit. The plug in work perfectly well on sites like www.ayoye.co and www.veuxturire.com. But on other sites, that uses the same pathern, it seems that the script is triggerd too early. For example there www.mondedestars.com and www.lesautos.ca triggers it too early.
If I use the "inject now" fonction of the Add on after the page is really done loading, then it redirects me to the youtube page as expected. I am lost on the why it works some where and not were else.
I'm not trying to understand every single website here, I'd prefer make it dynamicly triggered after the page has done loading everything from its php, ajax, script, flash, html and CSS.
I've tryed to look to the JWplayer API, but since its terribly unclear to me, over the fact that its partialy in flash, it woudl be simpler if there was a way to trigger it after, or maybe just triggering it after i hover over the body, since every sites has a body. It cant be specific to one page.
Use something like this
var timer;
function injectYouTube() {
// DO YOUR STUFF HERE
// ONCE DONE CALL clearInterval(timer);
clearInterval(timer);
}
timer = setInterval(injectYouTube, 2000);
I am not saying this will be called after everything is loaded but instead you can make sure your code is executed when you want it to.
The JWPlayer API are not that difficult. You can retrive the informations you need even not knowing the container id.
This is an example:
var player = jwplayer(0); // get the first jwplayer element of the page
var video = player.getPlaylistItem(); // get the player video
var url = video.file // retrieve the video url
I think the setTimeout or setInterval are unreliable.
Setting up a listener on jwplayer onReady event would be better.
The pessimistic answer to this is that you can't wait until a page has finished all AJAX operations etc. because web pages can continue loading new content indefinitely if they wish.
What you might consider is running your code every time a new HTML element is added to the page. This way, you can be certain to catch JWPlayer the moment it is inserted into the page.
document.addEventListener("DOMNodeInserted", yourRemovalFunction);

Reload page asynchronously or setTimeout?

I'm a bit lost.
I have two pages; Results and Detail. Whenever user navigates from Detail to Results using the browser back button, Results page should refresh, this way I can show what product user just seen on Detail (like amazon does with recently viewed items)
I don't know if it is better to load page asynchronously,
or use setTimeout as seen here (the example below works, but page refreshes forever)
if(window.top==window) {
// you're not in a frame so you reload the site
window.setTimeout('location.reload()', 3000); //reloads after 3 seconds
} else {
//you're inside a frame, so you stop reloading
}
and when I try reloading just a div also doesn't work
$('#div-id').triggerevent(function(){
$('#div-id').html(newContent);
});
I've also came across a lot of examples leading to this but didn't managed to make it work.
Any suggestion is welcome.
Thank you
The onload event should be fired when the user hits the back button. Elements not created via JavaScript will retain their values. I suggest keeping a backup of the data used in dynamically created element within an INPUT TYPE="hidden" or TEXTAREA set to display:none then onload using the value of the textbox to rebuild the dynamic elements to the way they were.
If you don't care about rebuilding the page and want to actually reload it, then you could do:
<input type="hidden" id="refreshed" value="no">
<script type="text/javascript">
onload=function(){
var e=document.getElementById("refreshed");
if(e.value=="no")e.value="yes";
else{e.value="no";location.reload();}
}
</script>
I believe you should reload the page asynchronously.
Maybe attaching the event ready to the body will work.
$(function(){
$('body').ready(function(){
alert('worked');
//Code to reload the page or data
});
});

JavaScript setTimeout will not die.

I made a photogallery and is AJAX powered. Below are the relevant pieces of code.
if (isset($_POST['stopss'])){
echo'<script type="text/javascript">
clearTimeout(setss);
</script>';
}
if (isset($_POST['startss'])){
?>
<script type="text/javascript">
var setss = window.setTimeout('delayer(\''+src+'\',\''+dir+'\',\''+title+'\',\''+width+'\',\''+height+'\',\''+img+'\')',5000);
</script>
<?
}
The delayer function passes params for a new modal box window (new AJAX request).
The problem as I see it. The timeout gets started when a user clicks the Slideshow button.
Even though they press the Stop Slideshow button (this reloads the AJAX page), the timer is still running (in the background) and in clearTimeout(setss), setss is no longer available (because of the new AJAX page request) so the clearTimeout fails to clear.
Is there any way to kill the timeout running in the background? Even if the modalbox window is closed, 5 seconds later it opens and happily keeps playing the slide show.
btw, this is the modalbox call.
Modalbox.show('../b-gal-scripts/ajaxgal.php', {title: title, overlayOpacity: .1, width: width, height: height, method: 'post', params: {src: next, dir: dir, img: img, ssimg: next} }); return false;
The problem
When you reload the page, the old JavaScript code (for the previous request) stops running and the new one is executed.
The problem is that you first call clearTimeout(setss) and later define what setss really is.
A couple additional problems
A few tips:
Do not mix quoting styles, you are creating a mess this way.
If you want quotes within quotes, just use the fact there are different quotes like that:
var setss = window.setTimeout("delayer('"+src+'","'+dir+'","'+title+'","'+width+'","'+height+'","'+img+'")',5000);
...and preferably get used to event-based programming and closures when coding JavaScript, like that:
var sets = window.setTimeout(function(){
delayer(src, dir, title, width, height, img);
}, 5000);
Final version of your code
Your code should look like the following:
if (isset($_POST['startss']) && !isset($_POST['stopss'])){
?>
<script type="text/javascript">
var setss = window.setTimeout(function(){
delayer(src, dir, title, width, height, img);
}, 5000);
</script>
<?
}
It makes use of the fact, that you do not need to first output a script that is executed only to immediately stop it if not needed. Just make PHP condition to check if you want it to be executed, the output it.
Second, the JS has been changed from using strings (which is totally messy) to using anonymous functions. Take a closer look into that.
Did it help?
I'm having a little difficulty understanding your problem, but I hope this helps.
When a page is reloaded, the previous instance of the page, and any state associated with it ceases to exist. As a result, the timeout has been stopped. Essentially, if the global setSS doesn't exist, then neither does the timeout to which it refers, therefore, that timeout cannot be responsible for starting the slideshow.
When an active page is served from something like PHP, the work of the server (WRT the creation of any content of the page) is done. No more content can subsequently be written to the page. Your clearTimeout is essentially useless, as it could only clear a timeout that is set during the load of the page. It won't write a new script element into the existing page.
Variables are not shared across pages, so if you are setting the timeout in one page, and clearing it in another, that will not work.
So, in order to clear the timeout, you need to call clearTimeout in the same page (and instance of that page) as the setTimeout, and that call must be executed after the setTimeout.
If none of the above apply to your situation, then is it possible that $_POST['startss'] and $_POST['stopss'] are set in the same request? If so, the new page will create a new timeout after the attempt to clear it, and will therefore display the slideshow.
(as an aside, using a closure to create a function to pass to setTimeout will be more readable than compiling a string that calls a function).

Categories

Resources