Newton Raphson method JS+html - javascript

Need help, because I have an error in my code and I can't see it.
I'm trying to do a newton raphson method.
The user enters a polinomy and the function calculates the derivate, then applys the Newton's raphson formula and shows the final result in a table.
My problem is that I can't make it work, because I can't show the final table with the results.
See an example here: http://codepen.io/anon/pen/Qyddoy?editors=101
Thats my JS code.
function funcion(func, x) {
var nuevaFuncion= func.replace(/x/g, x);
return eval(nuevaFuncion);
}
function derivada(x) {
var func = document.getElementsByName("func")[0].value.trim();
var derivative = nerdamer('diff(' + func + ')').evaluate();
}
function procesar(formulario) {
var i = 0;
var func = document.getElementsByName("func")[0].value;
var err, x_1, x = parseFloat(formulario.x.value);
var resultado = '<table border="3"><tr><td align="center">i</td><td align="center">x<sub></sub></td><td align="center">error</td></tr>';
do {
x_1 = x;
x = x - funcion(func, x) / derivada(x);
err = Math.abs((x - x_1) / x);
resultado += '<tr><td>x<sub>' + i + '</sub></td><td>' + x_1 + '</td><td>' + err + '</td></tr>';
i++;
} while (x != x_1 && i < 100);
document.getElementById('resultado').innerHTML = resultado + '</tbody> </table><br>' + (i == 100 ? 'La solucion no es convergente. ' : 'La solucion es ' + x);
return false;
}

There are a few things that I would do differently. The first is that I would avoid replacing and using eval and let nerdamer do the work. For example sin(x) would give an error since there isn't a native JS function called sin but rather Math.sin. I'm guessing your i < 100 is a safety. I prefer using a break statement since this is a lot easier to read and debug in my opinion. Also if you already know the variable name you can avoid calling buildFunction and use evaluate instead for example if the variable is x
nerdamer(func).evaluate({x:x});
And lastly, Newton's method requires some stop condition up to some accuracy. Your stop condition of x != x_1 is risky at best.
Here are my edits
http://codepen.io/anon/pen/gPgXbK?editors=101
function funcion(func, x) {
return nerdamer(func).buildFunction().call(undefined, x);
}
function derivada(x){
var func = document.getElementsByName("func")[0].value.trim();
return nerdamer('diff(' + func + ')').buildFunction().call(undefined, x);
}
function procesar(formulario) {
var i = 0;
var func = document.getElementsByName("func")[0].value;
var err, x_1, x = parseFloat(formulario.x.value);
var resultado = '<table border="3"><tr><td align="center">i</td><td align="center">x<sub></sub></td><td align="center">error</td></tr>';
do {
var x_1 = x - funcion(func, x) / derivada(x);
//get the error
var e = Math.abs(x-x_1);
x = x_1
err = Math.abs((x - x_1) / x);
resultado += '<tr><td>x<sub>' + i + '</sub></td><td>' + x_1 + '</td><td>' + err + '</td></tr>';
i++;
//I imagine that this is your safety so I would implement it like this
if(i > 100) break;
} while (e > 0.01);
document.getElementById('resultado').innerHTML = resultado + '</tbody></table><br>' + (i == 100 ? 'La solucion no es convergente. ' : 'La solucion es ' + x);
return false;
}

The function derivada doesn't return nothing so the division in procesar function fails.
You have to return a value so the calculus can go ahead. And I think you want to return the result of derivating the function, like this:
function derivada(x) {
var func = document.getElementsByName("func")[0].value.trim();
var derivative = nerdamer('diff(' + func + ')').evaluate();
return eval(derivative.text());
}

Related

A Game of Hand Cricket - Javascript

I am trying to make a simple game, in the below function handCricketBat(), the if conditional statement is getting skipped even when the condition batsMan = bowlerMan is satisfied. It always moves on to the else statement. Can someone tell me why this is happening.
function handCricketBat(){
var total = 0;
for (x = 1; x <=6; x++){
var batsMan = prompt("Ball " + x + " \nEnter Between 1-6");
var bowlerMan = randomBall();
console.log("The bowler - "+ bowlerMan);
if (batsMan === bowlerMan) {
console.log("Howzattt");
break;
}
else if (batsMan !== bowlerMan) {
console.log("That's good batiing, scoring a " + batsMan);
continue;
}
total += +batsMan;
}
console.log(total);
}
function randomBall(){
return Math.floor(Math.random()*7);
}
Your batsMan is a string.
Use var batsMan = parseInt(prompt("Ball " + x + " \nEnter Between 1-6")); instead and it should work.

Keep getting SyntaxError: missing ) after argument list

I keep getting this error due to these two lines:
document.getElementById('button').innerHTML = '<p><button
onClick = "MultiAnswer('+ questions[output] + ',' + answer[output]
+');">Submit</button></p>';
And I can't figure out what I am missing .
Edit: Here is the surrounding code (Excuse the mess) Contains methods that uses a switch statement to determine the input for the arrays required, from there puts it into the parameters for DisplayQuestion which then passes it to the functions below from the behaviour wanted:
function MultiQuest(questions, choices, answer){
var output = Math.floor(Math.random() * (questions.length));
var choicesOut = [];
document.getElementById('question').innerHTML = '<p id = "Q1">' + questions[output] + '<p><br>';
for(var k = 0;k < choices[output].length; k++ ){
choicesOut.push('<p><input id = "choice'+[k]+'" type = "radio" name = "option" value="'+choices[output][k]+'">' + choices[output][k] + '<p>');
}
document.getElementById('answers').innerHTML = choicesOut.join("");
document.getElementById('button').innerHTML = '<p><button onClick = "MultiAnswer('+ questions[output] + ',' + answer[output] +');">Submit</button></p>';
document.getElementById('score').innerHTML = '<p>' + score + '<p>';
}
function MultiAnswer(questions, answer, pageType){
var currentQuestion = document.getElementById('Q1').textContent;
var number = multiQuestions(currentQuestion, questions);
var correctAnswer = answer[number];
var givenAnswer;
var options = document.getElementsByName('option');
var i
for(i = 0; i < options.length; i++){
if(options[i].checked){
givenAnswer = options[i].value;
}
}
if(givenAnswer == correctAnswer){
alert("Right Answer!");
score++;
} else {
alert("Wrong Answer!");
score = 0;
}
i = 0;
DisplayQuestion(pageType);
}
function multiQuestions(currentQuestion, whichArray){
for(var i = 0; i < multiquestions.length; i++){
if(currentQuestion == whichArray[i]){
return i;
}
}
return null;
}
You cannot have a function call like this:
MultiAnswer('+ questions[output] + ',' + answer[output]
+')
You will need to evaluate the parameter in a seperate variable and then pass it in the function.
So in your onClick call of multiAnswer you have wrapped the 3 inputs in quotes. After referencing your multiAnswer function you do have the 3 inputs that you are looking for. You also have + signs on the ends of those inputs. You do not need to concatenate the parens inside of the function call.
I hope this helps!
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
onClick = "MultiAnswer(questions[output] + ',' + answer[output]
)">Submit</button></p>';

reading and writing to taffydb

I can't seem to get data from my taffyDB.
It has to be bad syntax but I don't know where.
My Javascript looks like this:
// init db
var procTech = TAFFY();
//..... other code in the middle
procTech().remove();
var x = 0;
$(".sxRow select[id^='KRCtech_']").each(function() {
var techName = $(this).val();
x++;
var xStr = x.toString();
clog(xStr + " " + techName);
procTech.insert({"count":xStr,"tech":techName });
});
var ret = eval(procTech().select("count","tech"));
clog(ret.length);
for (j = 0; j <= ret.length - 1; j++) {
clog("read back: " + [j][0] + "," + [j][1]);
}
// wrapper for console.log
function clog(s) {
window.console && console.log(s);
return;
}
console says:
1 tonya
2 shawn
2
read back: 0,undefined
read back: 1,undefined
so I know that
my initial values are good; i.e. they have value
Taffy sees 2 records, which is correct
It's just when I try and retrieve them, they are garbage.
What am I doing wrong?
procTech.insert({"count":1,"tech":'techName' });
procTech.insert({"count":2,"tech":'techName1' });
procTech.insert({"count":3,"tech":'techName2' });
procTech.insert({"count":3,"tech":'techName2' });
procTech.insert({"count":3,"tech":'techName2' });
procTech.insert({"count":4,"tech":'techName3' });
var query = procTech.select("count","tech"); // 3 rows
for ( var x=0; x<query.length-1; x++ ) {
console.log(query[x][0], query[x][1]);
}

Google Closure introducing errors

EDIT
The lesson, learned with the help of #Alex, is that you should never put function declarations in block scope. Not that I intended to do this, but if you slip up, it can cause big problems.
I have a script file that seems to be getting compressed via Google Closure incorrectly. When I run my app with the original code, all works fine. But when I try to compress it with Google Closure, some errors get introduced.
I am NOT using the advanced option; I'm using the basic, default mode
Obviously I can't expect anyone to debug the compressed file, but I'm hoping someone can look at the uncompressed code and let me know if I'm somehow doing something insanely stupid that would trick Closure.
Some notes on the minified code:
Closure is inlining BEFramework.prototype.hstreamLoad and BEFramework.prototype.hstreamEvalJson, and seems to be utterly removing the helper functions getDeleteValue, getValueToDisplay, getDisplayForLabel and likely others.
Uncompressed file is below.
This code can manually be compiled by closure here, which should reproduce the symptoms described above.
(function() {
var $ = jQuery;
// Load and display the messages ("healthstream") for a given module.
// This requires that the module's HTML have specific features, see
// dashboard.htm and contactsManager/details/default.htm for examples.
// This also requires that the `request` support `pageIndex` and `pageSize`,
// so we can handle paging.
//
// Args: `options` An options object with these keys:
// `channelId` The channel ID of the module (for transmitRequest)
// `translationId` Optional alternate ID for translation (if not given,
// `channelId` is used).
// `action` The action (for transmitRequest)
// - Must support `pageIndex` and `pageSize`
// `request` The request (for transmitRequest)
// - Must include `pageIndex` and `pageSize`
// `complete` Optional callback triggered when the load is complete.
// `showOptions` Optional callback if an options menu is supported
// by the calling module. Receives a raw event instance
// and the item on which the options were triggered:
// function showOptions(event, item)
// `context` Optional context (`this` value) for the call to
// `complete` and/or `showOptions`
BEFramework.prototype.hstreamLoad = hstreamLoad;
function hstreamLoad(options) {
var inst = this;
var channelId, translationId, action, request, complete, showOptions, context,
pageIndex, pageCount, pageSize, pageCount,
btnPrevious, btnNext,
dataShownFlags;
// Get our arguments (with defaults)
channelId = options.channelId;
translationId = options.translationId || options.channelId;
action = options.action;
request = $.extend({}, options.request); // Create a *copy*, because we modify it when doing paging
complete = options.complete;
if (typeof complete !== "function") {
complete = undefined;
}
showOptions = options.showOptions;
if (typeof showOptions !== "function") {
showOptions = undefined;
}
context = options.context; // (undefined will automatically become the global object)
// Grab the initial pageIndex and pageSize
pageIndex = request.pageIndex || 1;
pageSize = request.pageSize || 100;
// Disable the button and show "searching" label
$('#healthStreamSearchButton')
.button("disable")
.button("option", "label", BETranslate(translationId, 'HealthStreamSearching'));
// Hook up the buttons; be a bit paranoid that they've been hooked before and clear previous handlers
btnPrevious = $('#healthStreamPagePrevious');
btnNext = $('#healthStreamPageNext');
btnPrevious.hide().unbind("click.paging").bind("click.paging", goToPreviousPage);
btnNext.hide().unbind("click.paging").bind("click.paging", goToNextPage);
// Do it
doLoad();
// === Support functions
// Trigger a load request
function doLoad() {
request.pageIndex = pageIndex;
request.pageSize = pageSize;
inst._transport.transmitRequest(channelId, action, request, hstreamLoaded);
}
// Hndle the load response
function hstreamLoaded(objResponse) {
var healthStream = objResponse.items;
var total = objResponse.total;
var tbody = $('#healthStreamList');
// Need to make this update optional
$('#pageHeaderName').html(BETranslate(translationId, 'HeaderActivity') + ' (' + String(total) + ')');
$('#healthStreamSearchButton')
.button("enable")
.button("option", "label", BETranslate(translationId, 'HealthStreamSearch'));
tbody.empty();
btnPrevious.hide();
btnNext.hide();
if (healthStream.length > 0) {
pageCount = Math.ceil(total / pageSize);
if (pageCount > 1) {
if (pageIndex > 1) {
btnPrevious.show();
}
if (pageIndex < pageCount) {
btnNext.show();
}
}
var item;
var tr;
var tdMain;
var daysHash = {};
var creationDate;
var key;
var today = new Date();
var yesterday = new Date();
var msg;
yesterday.setDate(yesterday.getDate() - 1);
dataShownFlags = {};
for (var x = 0; x < healthStream.length; x++) {
item = healthStream[x];
msg = inst.hstreamEvalJson(item);
if (msg.length > 0) {
creationDate = new Date(item.CreationDate);
key = [creationDate.getYear(), creationDate.getMonth(), creationDate.getDate()].join('-');
if (!daysHash[key]) {
if (isDateEqual(creationDate, today)) {
addRowHeader(tbody, BETranslate(inst._channelId, 'HSToday'));
}
else if (isDateEqual(creationDate, yesterday)) {
addRowHeader(tbody, BETranslate(inst._channelId, 'HSYesterday'));
}
else {
addRowHeader(tbody, creationDate.toString('MM/dd/yyyy'));
}
daysHash[key] = true;
}
tr = $(
"<tr>" +
"<td class='date' style='white-space:nowrap;'>" + new Date(item.CreationDate).toString('h:mm tt') + "</td>" +
"<td class='main'><span class='name'>" + msg + "</span>" +
"</tr>"
);
tbody.append(tr);
if (showOptions) {
tr.find("td.main").prepend($("<em rel='opt'> </em>").click(makeShowOptionsHandler(item)));
}
}
}
// If any of the templates created links with a `data` attribute, hook them up
$('#healthStreamList a[data]').click(showTitle).each(function (index) {
this.id = 'data' + index;
});
}
else {
tbody.html('<tr><td colspan="2">' + BETranslate(inst._channelId, 'HSNoActivity') + '</td></tr>');
}
// Trigger completion callback
if (complete) {
complete.call(context, objResponse);
}
}
function makeShowOptionsHandler(item) {
// Our event comes to us from jQuery, but we pass on the raw
// event to the callback
return function (event) {
showOptions.call(context, event.originalEvent || event, item);
};
}
function addRowHeader(listRef, name) {
listRef.append(
"<tr>" +
"<td colspan='2' class='divider'>" + name + "</td>" +
"</tr>"
);
}
function showTitle(event) {
$.stopEvent(event);
var link = this;
var $link = $(this);
var href = $link.attr("href"); // We want the attribute, not the property (the property is usually expanded)
var hrefTitle = $link.attr('hreftitle') || BETranslate(inst._channelId, 'HSMoreInfo');
var data = $link.attr('data') || "";
var linkId = link.id;
if (!dataShownFlags[linkId]) {
dataShownFlags[linkId] = true;
if (data) {
var div = $(
"<div class='data'>" +
"<span data-linkId='" + linkId + "' class='close'>x</span>" +
"<table><thead></thead></table>" +
"</div>"
);
$link.parent().append(div);
var thead = div.find("thead");
var arr = data.split('~');
var splitEntry;
for (var x = 0; x < arr.length; x++) {
splitEntry = arr[x].split('|');
if (splitEntry[0] === 'Changed length') {
splitEntry[1] = splitEntry[1].replace(/\d+/g, BEFramework.prettyTime);
}
if (splitEntry.length > 1 && splitEntry[1].length > 0) {
thead.append(
"<tr>" +
"<td class='hslabel'>" + splitEntry[0] + ":</td>" +
"<td>" + splitEntry[1] + "</td>" +
"</tr>"
);
}
}
div.find("span:first").click(hideTitle);
if (href && href !== "#") {
$("<a target='_blank'>" + hrefTitle + "</a>").attr("href", href).appendTo(div);
}
}
}
}
function hideTitle(event) {
var $this = $(this),
linkId = $this.attr("data-linkId");
delete dataShownFlags[linkId];
$this.parent().remove();
return false;
}
function goToPreviousPage(event) {
--pageIndex;
doLoad();
return false;
}
function goToNextPage(event) {
++pageIndex;
doLoad();
return false;
}
}
var ___x = false;
var __i = 0;
BEFramework.prototype.hstreamEvalJson = hstreamEvalJson;
function hstreamEvalJson(item) {
var inst = this;
if (item.Action === 'saveinsurance' && !___x && __i != 0){
var start = +new Date();
__i = 1;
}
var userId = inst._BEUser ? inst._BEUser.getId() : -1;
var json = eval('(' + item.JSON + ')');
var key = 'HS' + item.Module + '_' + item.Action;
var msg = BETranslate(inst._channelId, key);
var fromIsMe = item.CreatedByContactId == userId;
var toIsMe = item.ContactId == userId;
var fromString = (fromIsMe) ? '<strong>' + BETranslate(inst._channelId, 'HSYou') + '</strong>' : '<a class="vcard" contactId="' + item.CreatedByContactId + '">' + item.CreatedByName + '</a>';
var toString = (toIsMe) ? '<strong>' + BETranslate(inst._channelId, 'HSYour') + '</strong>' : '<a class="vcard" contactId="' + item.ContactId + '">' + item.ContactName + '</a>';
var fromString2 = (fromIsMe) ? '<strong>' + BETranslate(inst._channelId, 'HSYour').toLowerCase() + '</strong>' : '<a class="vcard" contactId="' + item.CreatedByContactId + '">' + item.CreatedByName + '</a>';
var toString2 = (toIsMe) ? '<strong>' + BETranslate(inst._channelId, 'HSYou').toLowerCase() + '</strong>' : '<a class="vcard" contactId="' + item.ContactId + '">' + item.ContactName + '</a>';
var subFormat, subProps;
var configObject = (BEFramework.healthStreamConfig[item.Module] && BEFramework.healthStreamConfig[item.Module][item.Action]) || {};
var standardCase = configObject.standardCase;
var suppress = configObject.suppress || [];
var propertiesInOrder = configObject.displayOrder || [];
if (msg.indexOf('not found in module') != -1) {
try {
switch (item.Module) {
case 'contacts':
if (item.Action == 'setpermission' || item.Action == 'deleterelationship' || item.Action == 'addinvite') {
msg = BETranslate(inst._channelId, key + json.type.toString());
}
break;
case 'tasks':
if (item.Action == 'savetask') {
msg = BETranslate(inst._channelId, key + json.type.toString());
}
break;
default:
msg = '';
}
} catch (ex) {
msg = '';
}
}
for (var prop in json) {
if (typeof (json[prop]) == 'object') {
if (prop === 'changes' || prop === 'deleted'){
subProps = json[prop];
for (var propName in subProps) {
if (indexInArrayCI(propName, propertiesInOrder) === -1 && indexInArrayCI(propName, suppress) === -1){
propertiesInOrder.push(propName);
}
}
}
if (prop == 'changes') {
var changes = '';
var changeFrom = BETranslate(inst._channelId, 'HSChangedFrom');
var changeTo = BETranslate(inst._channelId, 'HSChangedTo');
for (var i = 0; i < propertiesInOrder.length; i++) {
var subprop = propertiesInOrder[i];
if (getObjectValCI(subProps, subprop) == null) continue;
var subSplit = stripHtml(getObjectValCI(subProps, subprop)).split('|');
if (subSplit.length === 1) {
subFormat = BETranslate(inst._channelId, 'HS' + item.Module + '_changes_' + subprop);
if (subFormat.indexOf('not found in module') < 0) {
changes += $.sandr(subFormat, '#{value}', subSplit[0]);
}
else {
changes += "*|" + subprop + " " + subSplit[0] + "~";
}
}
else {
var fromValue = stripHtml(subSplit[0]);
var toValue = stripHtml(subSplit[1]);
var packetInfo = processChangedValues(subprop, fromValue, toValue);
if (packetInfo.skip) continue;
changes = changes + changeFrom + packetInfo.display + '|' + packetInfo.fromValue + '<b>' + changeTo + '</b>' + packetInfo.toValue + '~';
}
}
msg = $.sandr(msg, '#{' + prop + '}', changes);
} else if (prop == 'deleted') {
var deleted = '';
for (var i = 0; i < propertiesInOrder.length; i++) {
var subprop = propertiesInOrder[i];
var currentValue = getObjectValCI(subProps, subprop);
if (currentValue == null || currentValue.toString().length === 0) continue;
deleted = deleted + getDisplayForLabel(subprop) + '|' + getDeleteValue(subprop, currentValue) + '~';
}
msg = $.sandr(msg, '#{' + prop + '}', deleted);
}
} else {
msg = $.sandr(msg, '#{' + prop + '}', $.sandr(json[prop], '"', ' '));
}
function processChangedValues(label, fromValue, toValue){
var typeFormat = (getObjectValCI(configObject, label) || {}).type;
var result = {};
if (typeFormat === 'date'){
var d1 = new Date(fromValue);
var d2 = new Date(toValue);
if (isDateEqual(d1, d2)) result.skip = true;
}
result.fromValue = getValueToDisplay(fromValue, typeFormat);
result.toValue = getValueToDisplay(toValue, typeFormat);
result.display = getDisplayForLabel(label)
return result;
}
function getDeleteValue(label, value){
var typeFormat = (getObjectValCI(configObject, label) || {}).type;
return getValueToDisplay(value, typeFormat);
}
function getValueToDisplay(rawValue, typeFormat){
if (typeFormat === 'date'){
var d = new Date(rawValue);
return isNaN(d.getTime()) ? rawValue : d.toString('MM/dd/yyyy');
} else if (typeof typeFormat === 'function') {
return typeFormat(rawValue)
} else {
return rawValue;
}
}
function getDisplayForLabel(label){
var fixCaseOfProperty = standardCase === '*' || indexInArrayCI(label, standardCase) > -1;
var rawConfigForLabel = getObjectValCI(configObject, label) || {};
return (rawConfigForLabel && rawConfigForLabel.display)
|| (fixCaseOfProperty ? fixCase(label) : null)
|| label;
}
}
msg = $.sandr(msg, '#{contactId}', item.ContactId);
msg = $.sandr(msg, '#{from}', fromString);
msg = $.sandr(msg, '#{to}', toString);
msg = $.sandr(msg, '#{from2}', fromString2);
msg = $.sandr(msg, '#{to2}', toString2);
msg = $.sandr(msg, '#{recordId}', item.RecordId);
msg = msg.replace(/#{[\S]*}/g, '');
if (item.Action === 'saveinsurance' && !___x && __i == 1){
var end = +new Date();
___x = true;
//alert(end - start);
}
if (item.Action === 'saveinsurance') __i++;
if (msg.indexOf('not found in module') == -1) {
return msg;
} else {
return '';
}
}
function stripHtml(html) {
var tmp = document.createElement('DIV');
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText;
}
function isDateEqual(date1, date2) {
if (date1.getDate() === date2.getDate() &&
date1.getMonth() === date2.getMonth() &&
date1.getYear() === date2.getYear()) {
return true;
}
else {
return false;
}
}
function getObjectValCI(obj, key){
for (var k in obj){
if (k.toLowerCase() === key.toLowerCase()){
return obj[k];
}
}
}
function indexInArrayCI(item, arr){
if (!$.isArray(arr)) arr = [];
var target = item.toString().toLowerCase();
for (var i = 0; i < arr.length; i++){
if (target === arr[i].toLowerCase()) return i;
}
return -1;
}
function fixCase(str){
return str.replace(/[a-z][A-Z]/g, function(match) { return match.charAt(0) + ' ' + match.charAt(1).toLowerCase(); }).toLowerCase()
.replace(/\sid\s/g, ' ID ')
.replace(/\sid$/g, ' ID')
.replace(/^id$/g, 'ID');
}
})();
When you use closure compiler you're giving up some control over your code. It will do all sorts of tricks, and potentially remove unused code.
It appears as though your functions are not removed, but are renamed.
For example, your call to getDeleteValue...
getDeleteValue(subprop, currentValue)
is now...
l(g,r)
Because getDeleteValue was not exported, Closure renamed it.
Working with Closure Compiler takes a bit of finesse and quite a bit of documentation scouring until you're familiar with how it works.
Well, there are too many errors to think of. First of all, I don't understand if you want static reference or instantiated values. You are not using jsDoc tags or anything like that. The Compiler does it's best work only with the corresponding jsDoc tag. You're logic is very weird and ill formulated. Prototype alternations, etc, all happening in an IIFE(immediately invoked function expression). Are your functions static? Are they constructors? Are we human or are we dancer?
an IIFE executes before the DOMContentLoaded event is fired by the browser. The most you can do is a jQuery IIFE equivalent $(function() {})(); which binds that to the DOMReady or DOMContentLoaded callback. You are defining inline functions inside blocks, which is not even in the ECMA Language.
While most script engines support Function Declarations within blocks it is not part of ECMAScript (see ECMA-262, clause 13 and 14). Worse implementations are inconsistent with each other and with future EcmaScript proposals. ECMAScript only allows for Function Declarations in the root statement list of a script or function. Instead use a variable initialized with a Function Expression to define a function within a block.
var myFunctionName = function (params) {};
You are also missing loads of semi-colons. Automatic semi-colon insertion on interpretation of your JS is not exactly flawless, so make a habit out of it.
Relying on implicit insertion can cause subtle, hard to debug problems. Don't do it. You're better than that.
There are a couple places where missing semicolons are particularly dangerous:
// 1.
MyClass.prototype.myMethod = function() {
return 42;
} // No semicolon here.
(function() {
// Some initialization code wrapped in a function to create a scope for locals.
})();
var x = {
'i': 1,
'j': 2
} // No semicolon here.
// 2. Trying to do one thing on Internet Explorer and another on Firefox.
// I know you'd never write code like this, but throw me a bone.
[normalVersion, ffVersion][isFF]();
var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] // No semicolon here.
// 3. conditional execution a la bash
-1 == resultOfOperation() || die();
So what happens?
JavaScript error - first the function returning 42 is called with the second function as a parameter, then the number 42 is "called" resulting in an error.
You will most likely get a 'no such property in undefined' error at runtime as it tries to call x[ffVersion][isIE]().
die is called unless resultOfOperation() is NaN and THINGS_TO_EAT gets assigned the result of die().
Why?
JavaScript requires statements to end with a semicolon, except when it thinks it can safely infer their existence. In each of these examples, a function declaration or object or array literal is used inside a statement. The closing brackets are not enough to signal the end of the statement. Javascript never ends a statement if the next token is an infix or bracket operator.
This has really surprised people, so make sure your assignments end with semicolons.

IE8 and 9 not supporting DOM. Can't find answer

I am running a DOM script and it is working PERFECTLY in Chrome and Firefox, but not IE8 or 9. The error messages in IE that I get are
document.getElementByld(..) is null or not an object
Object doesn't support this property or method
Unable to set value of the property 'innerHTML': object is null or undefined (URL: http://twitter.com/javascripts/blogger.js)
Code:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>
// DOM Ready
$(function() {
$.getJSON('http://twitter.com/status/user_timeline/LaunchSeven.json?count=2&callback=?', function(data){
$.each(data, function(index, item){
$('#twitter').append('<div class="tweet"><p>' + item.text.linkify() + '</p><p><strong>' + relative_time(item.created_at) + '</strong></p></div>');
});
});
function relative_time(time_value) {
var values = time_value.split(" ");
time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
var parsed_date = Date.parse(time_value);
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
delta = delta + (relative_to.getTimezoneOffset() * 60);
var r = '';
if (delta < 60) {
r = 'a minute ago';
} else if(delta < 120) {
r = 'couple of minutes ago';
} else if(delta < (45*60)) {
r = (parseInt(delta / 60)).toString() + ' minutes ago';
} else if(delta < (90*60)) {
r = 'an hour ago';
} else if(delta < (24*60*60)) {
r = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if(delta < (48*60*60)) {
r = '1 day ago';
} else {
r = (parseInt(delta / 86400)).toString() + ' days ago';
}
return r;
}
String.prototype.linkify = function() {
return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
return m.link(m);
});
};
});
</script>
Thank you in Advance,
Adam
Your page needs to have an element with the ID twitter_update_list...
document.getElementById('twitter_update_list').innerHTML = statusHTML.join('');
Can't say why it isn't available in IE without seeing more code.
Second argument. That's a function definition and not a function being fired. but if m.link(m) didn't work by itself, executing the function properly wouldn't work either.
String.prototype.linkify = function() {
return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
return m.link(m);
});
};
So just make the second arg m.link(m) (no semi)
I'm not sure this explains your document.getElementById issue though. But it might be causing a bug cascade somewhere.
Also, you should really define that string prototype before everything else. I believe only named functions hoist e.g. function someName(){.. vs. var someName = function(){...

Categories

Resources