I have a web worker that runs fine, until I try and set one of the parameters I'm passing to it. The code is:
//global variables
var xRange = [-2.5, 1];
function startWorker() {
if(typeof(Worker) !== "undefined") {
if(typeof(w) == "undefined") {
//xRange[0] = document.getElementById("xRange0").value;
//xRange[1] = document.getElementById("xRange1").value;
w = new Worker("myWorker.js");
w.postMessage({ "args": [xRange[0], xRange[1]] });
}
w.onmessage = function(event) {
//Do something.
};
} else {
//no ww support
}
}
If I un-comment the xRange[1] variable, the application runs as expected. However, if I un-comment the xRange[0] variable, the application does not produce expected results.
I checked that the items on the HTML page have the correct ID's.
I used alert(xRange[0]); after setting the array, and it confirmed that the value is whatever is inputted into the HTML page item.
I'm at a complete loss as to why one of these lines works, and the other does not.
Here's a fiddle with my source, so you can verify the item ID's are correct: http://jsfiddle.net/cxhrbf10/
One other thing that I've noticed, is that if I try to set more variables from page items in this location, the generation of the image goes from about 200ms to about 800ms. Just wondering why there was such a big performance hit just for accessing page item values.
Thanks!
Related
function goToPage(strFilePath)
{
//change iframe source to be the new one
try
{
$("#frameContent").attr("src",strFilePath);
} catch (error) {
var x = error;
}
}
the variable strFilePath would be something like: "location/page4.html"
When I run this code NORMALLY all it does is refresh the iframe with the same exact page, over and over- despite a different "strFilePath.html" being provided each time.
When I DEBUG this code in chrome, and step through it line by line using F9 or whichever key it is, it magically loads the correct page as expected.....
What gives??
This is how goToPage gets called ->
function nextButton()
{
//return the html path from the array that has the next corrosponding screenID, but if it is the last element in the array
//then we move them to the exam.
iCurrentScreenID = iCurrentScreenID + 1;
goToPage(arrLessonPages[iCurrentScreenID]);
}
I have a date input in my page, which I'm using Daterangepicker framework to populate it.
Here is the code of how I start my page!
$(function(){
startSelectors();
var variaveis = returnInputVars();
var rede = variaveis[0];
var codLoja = variaveis[1];
var period = variaveis[2];
console.log('1.'+rede+' 2.'+codLoja+' 3.'+period);
});
function returnInputVars(){
var rede = $("#dropdown-parceria").val();
var codLoja = $("#dropdown-loja").val();
var periodo = $("#datepicker-range").val();
return [rede, codLoja, periodo];
};
The function startSelectors() is set to start my datepicker and other fields, which is working perfectly. After it, I create a var called "variaveis" to fill
with the values of each field because I will use then later (this functions also works perfectly at other scripts of my page).
Running the page, my console returns this:
The funny thing is, if I type at the console this, the value is shown, just while starting the script is does not work!
Anybody experienced something like this?
***UPDATE
Adding this script to my start function:
console.log($("#datepicker-range"));
The value is shown, but the second console.log don't:
EDIT 1. FIDDLE (Suggested by #halleron)
To ensure things are loaded in the correct order, it is useful to apply a page sniffer code snippet that will scan the page continuously until a condition is met, or until a preset counter limit is reached (to prevent strain on browser memory). Below is an example of what I typically use that would fit your scenario.
I think because you are dealing with asynchronous loading, you can't have a global variable that holds the values in a global scope without an interval to detect when it can be used. Otherwise, it will attempt to read the variable when it is not yet ready.
You can invoke functions anywhere you like. But I would keep all of your variables contained within the page_sniffer_2017() because that is a controlled environment where you know that everything successfully loaded and you know that the variables are ready to be accessed without error.
That way, regardless of connection speed, your functions will only fire when ready and your code will flow, sequentially, in the right order.
Within the ajax success options, always add a class to the body of the document that you can search on to determine if it has finished loading.
$(document).ready(function() {
page_sniffer_2017();
});
function page_sniffer_2017() {
var counter = 0;
var imgScanner = setInterval(function() {
if ($("#datepicker-range").length > 0 && $("#datepicker-range").val().length && jQuery('body').hasClass('date-picker-successfully-generated')) {
var periodoDatepicker = $("#datepicker-range").val(); // ok
console.log(periodoDatepicker); // ok
var variaveis = returnInputVars(replaceDate(periodoDatepicker)); // ok
console.log(variaveis[0], variaveis[1], variaveis[2]);
//startNewSelectors(variaveis);
// start ajax call
generateData(variaveis[0], variaveis[1], variaveis[2]);
clearInterval(imgScanner);
} else {
//var doNothing = "";
counter++;
if (counter === 100) {
console.log(counter);
clearInterval(imgScanner);
}
}
}, 50);
}
So, I've got a notepad extension for Google Chrome that syncs and displays stored notes from a user. Currently my problem is as follows.
When the extension is run for the first time after download, the word 'undefined' is displayed in the editable div (id = edit_notepad). I want it to just be blank instead of displaying anything. Obviously, I know its undefined because the user hasn't been able to add any text yet.
Picture of what's displayed on initial run:
From my content script, here are my chrome.storage get and set functions (which do work):
document.body.onload = function() {
chrome.storage.sync.get("edit_notepad", function(items) {
if (!chrome.runtime.error) {
console.log(items);
document.getElementById("edit_notepad").innerHTML = items.edit_notepad;
}
});
}
document.getElementById("edit_notepad").onkeyup = function() {
var d = document.getElementById("edit_notepad").innerHTML;
chrome.storage.sync.set({ "edit_notepad" : d }, function() {
if (chrome.runtime.error) {
console.log("Runtime error.");
}
});
}
I presume I'm going to need some sort of if statement, but after hours of playing around, I'm lost as to what exactly it'd contain. The issue I've kept running into is that whatever I set the initial value of edit_notepad to, it always reverts back to "undefined" even when a user has written some notes! e.g. "This is a notes test" would revert back to "undefined" when the notepad is closed and reopened.
Well, an easy way to do this would be to specify a default value in your chrome.storage.sync.get(). Doing so would apply the default value when the key does not exist in the storage. However, given that you are replacing any contents which might already exist, the better solution would be not to set the contents when you have no value, or an invalid value, stored. The only valid value will be a string. This will prevent you from overwriting any default value supplied by the webpage when you have no value stored. Thus, an if statement something like the following should work (alternately, you could test for !== 'undefined':
document.body.onload = function() {
chrome.storage.sync.get("edit_notepad", function(items) {
if (!chrome.runtime.error) {
console.log(items);
if(typeof items.edit_notepad === 'string') {
document.getElementById("edit_notepad").innerHTML = items.edit_notepad;
}
}
});
}
Note: Storing the contents of the editable <div> on every key will result in many users running into both the MAX_WRITE_OPERATIONS_PER_MINUTE and MAX_WRITE_OPERATIONS_PER_HOUR quotas. You will need to have some other criteria for writing to storage.sync. Perhaps you could temporarily store the value in storage.local and only to storage.sync every couple of minutes.
I'm trying to save an object with rhaboo in javascript. The first time after initialising it is working but when I'm trying to save it again it gives me the
rhaboo.min.js:1 Uncaught TypeError: Cannot read property 'refs' of undefined error. I pinned down the error to the line where I save the keyArray with notes.write('presentationNotes', keyArray);
How I get the error in detail:
I open my webapplication with a clean localStorage (nothing is saved) and rhaboo gets initialised. After that I navigate to a document and open the notes-div with the notes-button. I write something in the notes-area and hit the notes-submit button to save the notes with rhaboo to localStorage. I do the same for a second document. For now everything works. Both notes get saved correctly so that I have an object like this:
keyArray = {activeDoc1: ['note1', 'note2'], activeDoc2: ['note1', 'note2']}
saved in rhaboo in notes.presentationNotes. Then I reload my webapplication and rhaboo is already initialised. I navigate to the documents as before and check if I can load the saved notes. This works as expected but when I try to hit the notes-submit button again it gives me the aforementioned error. What am I doing wrong?
var notes = Rhaboo.persistent('Presentation Notes');
$(document).ready(function(event) {
var keyArray, activeDoc;
if (!notes.initialised) {
notes.write('initialised', true);
notes.write('presentationNotes', {});
console.log('Rhaboo Initialised');
keyArray = {};
} else {
console.log('Rhaboo already initialised');
keyArray = notes.presentationNotes;
console.log('notes.presentationNotes onLoad = ');
console.log(notes.presentationNotes);
}
//Notes open
$(document).on('click', '#notes-button', function() {
$('.notes-div').show();
activeDoc = $('.node.active').attr('id');
if (notes.presentationNotes[activeDoc] != null) {
//Iterate notes
$.each(notes.presentationNotes[activeDoc], function(index, value) {
$('#notes-area').append(value + '\n');
});
}
});
//Notes save
$(document).on('click', '#notes-submit', function() {
$('.notes-div').hide();
var str = $('#notes-area').val();
var array = str.split("\n");
keyArray[activeDoc] = array;
//Save notes
notes.write('presentationNotes', keyArray);
//Clear textarea
$('#notes-area').val('');
});
}
Without the HTML I haven't been able to try this, so I'm just guessing here, but I suspect your problem will go away if you stop using keyArray and activeDoc. The whole point of rhaboo is that it is not a place to store your data. It IS your data.
I see no transient data in your program, i.e., no data which you actively want to delete when the user goes away and comes back. All the data is supposed to be persistent, therefore it should all be under the Rhaboo.persistent.
That's the philosophy, but to be more specific, I think your problem is here:
keyArray[activeDoc] = array;
When I wonder what keyArray is is find:
keyArray = notes.presentationNotes;
so the earlier line actually says:
notes.presentationNotes[activeDoc] = array;
but it says on the tin that that should read:
notes.presentationNotes.write(activeDoc, array);
The upshot is that that the hooks that make rhaboo work have not been inserted into array, as notes.presentationNotes.write would have done.
When you next said:
notes.write('presentationNotes', keyArray);
it meant:
notes.write('presentationNotes', notes.presentationNotes).
which is clearly not what you meant. Rhaboo doesn't suspect that array has no hooks yet because it can see that notes.presentationNotes does have hooks.
I also forget to use write sometimes, and it really bugs me that JS offers no way to hook into the creation of a NEW key within an object X, no matter what you've done to X. Without that limitation, there'd be no need for write and it could be foolproof.
I'm new to HTML and Javascript, and to learn it I am making an incremental game (similar to CookieClicker or CivClicker).
I'm trying to save and load progress, and I can save it just fine, but when I load it, it loads all the variables correctly, but when I click on a button to increment a variable, it does some weird stuff, it's hard to explain, I'll post the code so you can look at it some more.
JSFiddle Here
function loadProgress() {
if (typeof (Storage) !== "undefined") {
progress = localStorage.progress;
speed = localStorage.speed;
quality = localStorage.quality;
isDone = localStorage.isDone;
totalMoney = localStorage.totalMoney;
speedCost = localStorage.speedCost;
gamesSold = localStorage.gamesSold;
autoclick = localStorage.autoclick;
autoclickCost = localStorage.autoclickCost;
currentBugs = localStorage.currentBugs;
refreshDisplay();
} else {
console.log("LocalStore not appliable.")
}
}
Press 'Design' until you get to 100% then click 'Sell your game'. Then just press Save Progress then Load progress and click design and sell game again, you will see the numbers increase very oddly and that isn't expected at all.
'ShowMeTheMoney' will show you the variables in the console so you can verify that the variables were stored correctly.
I have no idea why this is happening, so if someone could help that would be awesome.
Local storage aka Web Storage, stores values as strings, so you need to convert/cast to numbers when you retrieve the values, otherwise the variables will remain as strings, and you'll see concatenation instead of the value being incremented. For example 1 + 1 becomes 11 not 2.
Updated working fiddle
There are many ways of converting to a number, one way is the + method:
progress = +localStorage.progress;
speed = +localStorage.speed;
quality = +localStorage.quality;