I'm loading a dynamic application (which takes 20-30 seconds), and I'm trying to create a dynamic progress bar that shows the user how much of the task has been completed dynamically as the page loads.
I'm accomplishing this by setting buffer to false and having my script output a line of JavaScript as it progresses that calls a function to increment the scrollbar:
function progress(percent)
{
$(function() {
$("#progressbar").progressbar({value: Math.round((percent*100))});
});
}
This is called by s simple function call like progress(15) generated by my page and sent realtime to the browser. A simple bar I made with css worked perfectly, but now that I'm trying to use jQuery it seems my progress bar is being incremented correctly but it won;t show up on the page until the page is done loading or the "stop" button is pressed. Any ideas why this is?
you're using the shorthand equivalent of the 'document.ready' notation $(function(){}); which only fires after the dom is loaded
if your function wasn't wrapped with that you'd be all set
i.e.
function progress(percent)
{
$("#progressbar").progressbar({value: Math.round((percent*100))});
}
Are you wrapping it in the $(document).ready( callback? If so that's the issue. $(document).ready won't run until the DOM has been loaded.
It could also be that if the page is loading it hasn't run the JS yet, or the #progressbar wasn't found in the DOM. This could be because you're calling the function before the #progressbar div is written.
Correct:
<div id="progressbar"></div>
<script type="text/javascript">/* Function call */</script>
Incorrect:
<script type="text/javascript">/* Function call */</script>
<div id="progressbar"></div>
I recommend making the page template (headers, footers, etc, everything that doesn't require a lot of server side processing) and then putting in the progressbar attached to a $.load AJAX call.
Related
Let me preface this by saying I want a spinner...
I don't necessarily care whether it loads when the page first starts up, or later. The problem I'm experiencing also doesn't seem to care, as I've tried it both ways.
Right this moment, I don't declare it at the top of the page. Because I have a lot of visualization stuff going on, I start that up and immediately pass some info to the spinner (which also starts it up):
google.load('visualization', '1', {packages:['controls'], callback: initializeTables});
function initializeTables() {
provideInfo("loading proficiencies (Step 1/12)");
//etc... }
function provideInfo(text) {
$.mobile.loading( "show", {
text: text,
textVisible: true
});
}
So that starts... fine... ish...
The problem is that there's actually two spinners started when that starts - one in front, one behind. Because the one in front is slightly offset from the one behind, I can see both.
If I later call:
$.mobile.loading( "hide" );
It only hides the front one, not the back one.
I've found I can hide both by saying:
$(".ui-loader").hide();
Which is great. But, I'd like to not see two in the first place. I've tried to puzzle out the jquery mobile documentation page, to no avail (it also mentions a "global method docs" but I haven't been able to find that link):
//This does not work:
$( ".ui-loader" ).loader( "option", "text", "Loading Page..." );
//Nor does this:
$( "#notify_div" ).loader( "show" );
$( "#notify_div" ).loader( "option", "text", "Loading Page..." );
Anyone know how to get it all into one spinner, or why it's loading two?
Sadly, the current JQM documentation is for the 1.5 version which hasn't be released yet. You need to look directly at the source code of the 1.4.5 version.
There is a JQM default which is showing the spinner when a page is loading. You can override this behavior at JQM initialization.
<script type="application/javascript" src="js/jquery-2.2.4.js"></script>
<script>
$(document).on("mobileinit", function () {
$.mobile.changePage.defaults.showLoadMsg = false;
});
</script>
<script type="application/javascript" src="js/jquery.mobile-1.4.5.js"></script>
If You look at line 5847 of the JQM uncompressed source code, You will find all the configurable settings for that.
Moreover, just for the sake of completeness, there is another setting where You can tell JQM to not show the spinner for already cached pages. Just look at line 5122 of the JQM uncompressed source code:
// This delay allows loads that pull from browser cache to
// occur without showing the loading message.
loadMsgDelay: 50
Hope this help.
I'm trying to display some information on an HTML web page when the viewer loads the web page. I have a function, called getID(email), that returns an integer. I know that this works, as I've tested with console and it works properly. My issue is being able to display the return of getID() onto the web page when the page loads.
I know that I have to use document.getElementById('div id goes here').innerHTML('content goes here'); to change what a div says, but for the life of me I can't get the actual information.
Here's what I have:
<div id='output'>
</div>
<script>
function showId() {
var id = google.script.run.getId(Session.getActiveUser().getEmail());
document.getElementById('output').innerHTML(id);
</script>
I have no idea how to make this run when the HTML page is loaded. Help is appreciated!
You can just put the script on the bottom of the page and call the showId function:
<script>
// you can define showId here
showId();
</script>
If you can't put the script at the very end or you expect to be using other scripts and want to only execute after everything is loaded you can just wait for the DOMContentLoaded event:
window.addEventListener('DOMContentLoaded', function() {
function showId() {
// ...
}
showId();
});
Currently I'm trying to use zombie.js to run automated tests for my website. Right now I'm working on automating a person signing up. For the signup a form is used with 3 different divs that look like this
Page Code:
<form>
<div id=step1>
<div id=step2>
<div id=step3>
</form>
...
...
<button id="nextStep" class="btn btn-primary" role="button"
onClick="signupNext()">Cnt. </button>
SignupNext is a javascript function which disables the button then some simple things
then re-enables the button.
Zombie Code:
browser
.visit(https://example.com, function(){
browser.fill(....)
browser.fill(....)
browser.pressButton('#nextStep', function(){
browser.fill(...)
browser.fill(...)
browser.pressButton('#nextStep', function(){ //THIS LINE Errors
...
...
});
});
})
Zombie throws the error "Button is disabled" on the second .pressButton. As far as my understanding of zombiejs goes it seems to me like the pressButton should wait for the event to finish then execute the callback function.
*new to zombiejs
Everythings happen asynchronously
From documentation :
The browser will load the document and if the document includes any scripts, also load and execute these scripts. It will then process
some events, for example, anything your scripts do on page load. All
of that, just like a real browser, happens asynchronously.
To wait for the page to fully load and process events, you pass visit
a callback function. Zombie will then call your callback with null,
the browser object, the status code of the last response, and an array
of errors (hopefully empty). This is JavaScript, so you don't need to
declare all these arguments, and in fact can access them as
browser.statusCode and browser.errors.
(Why would the first callback argument be null? It works great when
using asynchronous testing frameworks like Mocha
Zombie also supports promises. When you call functions like visit,
wait or clickLink without a callback, you get a promise. After the
browser is done processing, it either fulfills or rejects the promise.
For example:
browser.visit("http://localhost:3000/").
then(function() {
assert.equal(browser.text("H1"), "Deferred zombies");
}).
fail(function(error) {
console.log("Oops", error);
});
It might be due to the way you're checking input to enable/disable this button.
I'm guessing you're probably using either keyup, blur or both events.
When zombie is filling these inputs for you, it doesn't bother with firing these events as when a real user fills it up using an actual browser, you'll have to use zombie to fire whichever event you need, right after the input is filled up, like this:
browser.fill(...);
browser.fill(...);
browser.fire("{checkedInputSelector}", "keyup", function(){
browser.pressButton('#nextStep', function(){ //THIS LINE shouldn't error anymore
...
...
});
});
Sometime if we embed widgets and when the DOM is fully loaded (showed by jquery's $(document).ready()
said it so), it still needs time for widgets to show (or load) from its servers (e.g. www.widgetbox.com). How to give a loader image for each widgets in that time lag? Any idea?
In the html, put a 'loading' image in place of the widget, then remove or hide the image when the widget is loaded.
The correct place to do this would be in the window load event.
window.onload = function () {
// hide the 'loading' image
}
In Google Chrome's extension developer section, it says
The HTML pages inside an extension
have complete access to each other's
DOMs, and they can invoke functions on
each other. ... The popup's contents
are a web page defined by an HTML file
(popup.html). The popup doesn't need
to duplicate code that's in the
background page (background.html)
because the popup can invoke functions
on the background page
I've loaded and tested jQuery, and can access DOM elements in background.html with jQuery, but I cannot figure out how to get access to DOM elements in popup.html from background.html.
can you discuss why you would want to do that? A background page is a page that lives forever for the life time of your extension. While the popup page only lives when you click on the popup.
In my opinion, it should be refactored the other way around, your popup should request something from the background page. You just do this in the popup to access the background page:
chrome.extension.getBackgroundPage()
But if you insist, you can use simple communication with extension pages with sendRequest() and onRequest. Perhaps you can use chrome.extension.getViews
I understand why you want to do this as I have run into the problem myself.
The easiest thing I could think of was using Google's method of a callback - the sendRequest and onRequest methods work as well, but I find them to be clunky and less straightforward.
Popup.js
chrome.extension.getBackgroundPage().doMethod(function(params)
{
// Work with modified params
// Use local variables
});
Background.html
function doMethod(callback)
{
if(callback)
{
// Create/modify params if needed
var params;
// Invoke the callback
callback(params);
}
}
As other answers mention, you can call background.js functions from popup.js like so:
var _background = chrome.extension.getBackgroundPage();
_background.backgroundJsFunction();
But to access popup.js or popup.html from background.js, you're supposed to use the messages architecture like so:
// in background.js
chrome.runtime.sendMessage( { property: value } );
// in popup.js
chrome.runtime.onMessage.addListener(handleBackgroundMessages);
function handleBackgroundMessages(message)
{
if (message.property === value)
// do stuff
}
However, it seems that you can synchronously access popup.js from background.js, just like you can synchronously access the other way around. chrome.extension.getViews can get you the popup window object, and you can use that to call functions, access variables, and access the DOM.
var _popup = chrome.extension.getViews( { type: 'popup' } )[0];
_popup.popupJsFunction();
_popup.document.getElementById('element');
_popup.document.title = 'poop'
Note that getViews() will return [] if the popup is not open, so you have to handle that.
I'm not sure why no one else mentioned this. Perhaps there's some pitfalls or bad practices to this that I've overlooked? But in my limited testing in my own extension, it seems to work.