CrossBrowser Js Listener [duplicate] - javascript

This question already has an answer here:
adding event listener cross browser [closed]
(1 answer)
Closed 9 years ago.
Okay so currently this is what i found from my predecessor and the code has stopped working so it's my job to fix it or at least patch it up..
simply I'd like to condense this into a smaller function that detects which event listener to use..
//EI 9
var formsCollection = document.getElementsByTagName("form");
var chain = "";
for(var i=0;i<formsCollection.length;i++)
{
// alert(formsCollection[i].name);
formsCollection[i].addEventListener('submit', function() {
//working fine
var formsCollection1 = document.getElementsByTagName("form");
for (x = 0 ; x < formsCollection1.length; x++)
{
var elements1 = formsCollection1[x].elements;
for (e = 0 ; e < elements1.length; e++)
{
chain += elements1[e].name + "%3d" + elements1[e].value + "|";
}
}
attachForm(chain);
//end mid
}, false);
}
function attachForm(data) {
// alert(data);
var oImg=document.createElement("img");
oImg.setAttribute('src', "URL" POST);
oImg.setAttribute('alt', 'na');
oImg.setAttribute('height', '1px');
oImg.setAttribute('width', '1px');
document.body.appendChild(oImg);
}
//IE8
var formsCollection = document.getElementsByTagName("form");
var chain = "";
for(var i=0;i<formsCollection.length;i++)
{
// alert(formsCollection[i].name);
formsCollection[i].attachEvent('onsubmit', function() {
//working fine
var formsCollection1 = document.getElementsByTagName("form");
for (x = 0 ; x < formsCollection1.length; x++)
{
var elements1 = formsCollection1[x].elements;
for (e = 0 ; e < elements1.length; e++)
{
chain += elements1[e].name + "%3d" + elements1[e].value + "|";
}
}
attachForm(chain);
//end mid
}, false);
}
function attachForm(data) {
// alert(data);
var oImg=document.createElement("img");
oImg.setAttribute('src', "URL POST");
oImg.setAttribute('alt', 'na');
oImg.setAttribute('height', '1px');
oImg.setAttribute('width', '1px');
document.body.appendChild(oImg);
}

If you use this wrapper
function addEvent(element,theEvent,handler) {
if(element.addEventListener) elemenet.addEventListener(theEvent,handler);
else if(element.attachEvent) elemenet.attachEvent("on"+theEvent,handler);
}
You can use in both cases
addEvent(formsCollection[i],'submit', function() { ... });

Related

iteration inside addEventListener not working [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
i created a very simple toggle function.
I have 6 div-Tags with individual id's and 6 a-Tags
Why i can't use the loop-variable to iterate through the id's?
<script>
var open = false;
var boxes = document.getElementsByClassName("boxlink");
for (var i = 0; i < boxes.length; i++) {
boxes[i].addEventListener("click", function () {
var b = document.getElementById("textbox" + i);
toggle(b);
}
, false);
}
function toggle(obj) {
if (open == false) {
obj.style.height = 'auto';
open = true;
}
else {
obj.style.height = '78px';
open = false;
}
}
</script>
You have to create a closure in the loop
// Code goes here
var open = false;
var boxes = document.getElementsByClassName("boxlink");
for (var i = 0; i < boxes.length; i++) {
var onClickFunction = (function(i) {
return function() {
var b = document.getElementById("textbox" + i);
toggle(b);
}
})(i);
boxes[i].addEventListener("click",onClickFunction , false);
}
function toggle(obj) {
if (open == false) {
obj.style.height = 'auto';
open = true;
} else {
obj.style.height = '78px';
open = false;
}
}

getElementsByClassName doesn't work on IE6. What am I doing wrong?

My script works on IE7, 8, 9, etc., Chrome, Firefox, Safari, etc. But when I run this on IE6, it doesn't work. It is a calculate function like a bet vs cash on bank = transfer.
What am I doing wrong?
Here's a working sample:
var a, p = document.getElementsByClassName("preAmount");
var mark = new Array();
$(function () {
$('input').each(function () {
$(this).keyup(function () {
var w = $(this).val(),
n = w.indexOf("."),
z = w.indexOf("0");
//allow 2 digit decimal
if (n > 0 && (w.length - n) > 3) {
$(this).val(parseFloat(w.substring(0, n) + w.substring(n, n + 3)));
}
//reset beginning with zero
if (z == 0) {
$(this).val(w * 1);
}
//set zero
if (isNaN(w) || w.length == 0) {
$(this).val("0");
}
calculateTotal($(this));
});
});
$(".enableOnInput").click(function () {
var submitValid = false;
if (mark.length > 0) {
for (k = 0; k < mark.length; k++) {
// if one of the mark in array is true, it's valid to submit
if (mark[k] == true) {
submitValid = true;
break;
};
}
}
if (submitValid) {
window.open("success.html", "_self");
} else {
alert('您尚未更新游戏平台转帐资金!\n\nYou have not alter transfer amount!');
}
});
$(".reset").click(function () {
a = document.getElementsByClassName('namount');
for (k = 0; k < a.length; k++) {
a[k].value = parseFloat(p[k].innerHTML, 10);
}
$('.balance-value').text($('.t-right-title-balance').text());
mark = new Array();
});
});
function cal() {
var ta = 0,
tp = 0,
tb = parseFloat($('.t-right-title-balance').text());
a = document.getElementsByClassName('namount');
for (j = 0; j < p.length; j++) {
var ttp, tta;
ttp = parseFloat(p[j].innerHTML);
tta = parseFloat(a[j].value);
tp += ttp;
ta += tta;
mark[j] = (ttp != tta); //set alter mark of each platform
}
return (tb + tp - ta);
}
function calculateTotal(src) {
var sumtable = src.closest('.sumtable');
sumtable.find('input').each(function () {
var preAmount = $(this).parent().parent().find('.preAmount').text();
var curAmount = this.value;
if (!isNaN(this.value) && this.value.length != 0) {
preAmount = parseFloat(preAmount);
curAmount = parseFloat(this.value);
var f = parseFloat($('.t-right-title-balance').text()).toFixed(2);
var transAmount = curAmount - preAmount;
if (curAmount < 0 || transAmount > f) {
this.value = preAmount;
$('.balance-value').text(f);
return;
} else {
var b = parseFloat($('.balance-value').text());
var tb = cal();
if (tb >= 0) {
$('.balance-value').text(tb.toFixed(2));
} else {
this.value = preAmount; //illegal rollback
$('.balance-value').text(tb.toFixed(2));
return;
}
}
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I don't know to tag the correct answer, but this is what fixed it,
From: #Phil - I imagine you'd have a little trouble with document.getElementsByClassName (minimum IE support is v9). Use the jQuery selector instead, eg $('.namount')
According to W3C:
The getElementsByClassName() method is not supported in Internet Explorer 8 and earlier versions.
I'm pretty sure that's right.
<!DOCTYPE html>
<html>
<body>
<p class="demo">Test.</p>
<button onclick="myFunction()">Click me!</button>
<script>
function myFunction() {
document.getElementsByClassName('demo').innerHTMl = "Hallo!";
}
</script>
</body>
</html>
You can try this on Internet Explorer 6 or 5.

javascript: How to build a function that refers to the variables in my Quiz app?

I recently built a small quiz application, it currently only has two questions. After all the questions are finished I would like for the app to present a page that says "You made it here" (eventually I'll add more). However for some reason the final-function feedback of this code is not working. Where am I going wrong?
$(document).ready(function () {
var questions = [
{question: "Who is Zack Morris?",
choices: ['images/ACslater.jpg','images/CarltonBanks.jpeg','images/ZachMorris.jpg'],
quesNum: 1,
correctAns: 2},
{question: "Who is Corey Matthews?",
choices: ['images/CoryMatthews.jpeg','images/EdAlonzo.jpg','images/Shawnhunter.jpg'],
quesNum: 2,
correctAns: 1},
];
var userAnswer //THis needs to be looked into
var counter = 0;
var score = 0;
var html_string = '';
var string4end = ''
//function to loop choices in HTML, updates counter, checks answer
var update_html = function(currentQuestion) {
// put current question into a variable for convenience.
// put the question string between paragraph tags
html_string = '<p>' + currentQuestion.question + '</p>';
// create an unordered list for the choices
html_string += '<ul>';
// loop through the choices array
for (var j = 0; j < currentQuestion.choices.length; j++) {
// put the image as a list item
html_string += '<li><img src="' + currentQuestion.choices[j] + '"></li>';
}
html_string += '</ul>';
$('.setImg').html(html_string);
}
update_html(questions[0]);
$('.setImg li').on('click', function (e) {
userAnswer = $(this).index();
checkAnswer();
counter++;
update_html(questions[counter]);
$('#score').html(score);
showFinalFeedback();
});
//function to identify right question
function checkAnswer ()
{
if (userAnswer === questions[counter].correctAns)
{
score=+100;
}
}
function showFinalFeedback ()
{
if (counter === (questions.length+1))
{
string4end = '<p>' + 'You made it here!!!!' + '</p>';
$('.setImg').html(string4end);
}
}
});
I agree with Vector that you either should start with 1 as Counter initialization or, to check
if (counter < questions.length) {
return;
}
alert('You \'ve made it till here');
I also rewrote it in a form of a jquery plugin, maybe a handy comparison to your way of working?
jsfiddle: http://jsfiddle.net/DEb7J/
;(function($) {
function Question(options) {
if (typeof options === 'undefined') {
return;
}
this.chosen = -1;
this.question = options.question;
this.options = options.options;
this.correct = options.correct;
this.toString = function() {
var msg = '<h3><i>' + this.question + '</i></h3>';
for (var i = 0; i < this.options.length; i++) {
msg += '<a id="opt' + i + '" class="answer toggleOff" onclick="$(this.parentNode).data(\'quizMaster\').toggle(' + i + ')">' + this.options[i] + '</a>';
}
return msg;
};
this.toggle = function(i) {
var el = $('#opt' + i);
if ($(el).hasClass('toggleOff')) {
$(el).removeClass('toggleOff');
$(el).addClass('toggleOn');
} else {
$(el).removeClass('toggleOn');
$(el).addClass('toggleOff');
}
};
}
function Quiz(elem, options) {
this.element = $(elem);
this.lastQuestion = -1;
this.questions = [];
this.correct = 0;
if (typeof options !== 'undefined' && typeof options.questions !== undefined) {
for (var i = 0; i < options.questions.length; i++) {
this.questions.push(new Question(options.questions[i]));
}
}
this.start = function() {
this.lastQuestion = -1;
this.element.html('');
for (var i = 0; i < this.questions.length; i++) {
this.questions[i].chosen = -1;
}
this.correct = 0;
this.next();
};
this.next = function() {
if (this.lastQuestion >= 0) {
var p = this.questions[this.lastQuestion];
if (p.chosen === -1) {
alert('Answer the question first!');
return false;
}
if (p.chosen === p.correct) {
this.correct++;
}
$(this.element).html('');
}
this.lastQuestion++;
if (this.lastQuestion < this.questions.length) {
var q = this.questions[this.lastQuestion];
$(this.element).html(q.toString());
console.log(q.toString());
} else {
alert('you replied correct on ' + this.correct + ' out of ' + this.questions.length + ' questions');
this.start();
}
};
this.toggle = function(i) {
if (this.lastQuestion < this.questions.length) {
var q = this.questions[this.lastQuestion];
q.toggle(q.chosen);
q.toggle(i);
q.chosen = i;
}
};
}
$.fn.quizMaster = function(options) {
if (!this.length || typeof this.selector === 'undefined') {
return;
}
var quiz = new Quiz($(this), options);
quiz.start();
$(this).data('quizMaster', quiz);
$('#btnConfirmAnswer').on('click', function(e) {
e.preventDefault();
quiz.next();
});
};
}(jQuery));
$(function() {
$('#millionaire').quizMaster({
questions: [
{
question: 'Where are the everglades?',
options: ['Brazil','France','USA','South Africa'],
correct: 2
},
{
question: 'Witch sport uses the term "Homerun"?',
options: ['Basketball','Baseball','Hockey','American Football'],
correct: 1
}
]
});
});
Hey guys thanks for your help. I was able to use the following work around to ensure everything worked:
$('.setImg').on('click', 'li', function () {
userAnswer = $(this).index();
checkAnswer();
counter++;
$('#score').html(score);
if (counter < questions.length)
{
update_html(questions[counter]);
}
else{
showFinalFeedback();
}
});

banner ads not visible in html page

i have a file banners.js
function addEvent(object, evName, fnName, cap) {
if (object.attachEvent)
object.attachEvent("on" + evName, fnName);
else if (object.addEventListener)
object.addEventListener(evName, fnName, cap);
}
var nextAd;
function makeBannerAds() {
var bannerBox = document.createElement("div");
bannerBox.id = "bannerBox";
document.body.appendChild(bannerBox);
for (var i=0; i<adsURL.length; i++) {
var bannerAd = document.createElement("div");
bannerAd.className = "bannerAd";
bannerAd.style.zIndex = i;
var urlLink = document.createElement("a");
urlLink.href = adsURL[i];
var bannerIndex = document.createElement("img");
bannerIndex.src = "banner" + i +".jpg";
bannerIndex.style.width="290px";
bannerIndex.style.height="55px";
bannerBox.appendChild(bannerAd);
}
bannerBox.appendChild(bannerAd);
setInterval("changeBannerAd()", 10000);
}
function changeBannerAd() {
var allAds = document.getElementById("bannerBox").childNodes;
alert('work');
for(var i=0; i<num; i++) {
if(allAds.style.zIndex == 0) {
allAds.style.top = "-50px";
nextAd = allAds;
}
}
for(var i=0; i<num; i++) {
allAds.style.zIndex--;
if(allAds.style.zIndex < 0)
allAds.style.zIndex = num-1;
}
var timeDelay = 0;
for(var i=-50; i<=0; i++) {
setTimeout("moveNextAd(" + i + ")", timeDelay);
timeDelay += 15;
}
}
function moveNextAd(top) {
nextAd.style.top = top + ".px"
}
addEvent(window, "load", makeBannerAds(), false);
the second file
ads.js
var adsURL = new Array();
//this stores each item in the array using a index place holder
adsURL[0] = "testpage0.htm";
adsURL[1] = "testpage1.htm";
adsURL[2] = "testpage2.htm";
adsURL[3] = "testpage3.htm";
adsURL[4] = "testpage4.htm";
adsURL[5] = "testpage5.htm";
adsURL[6] = "testpage6.htm";
adsURL[7] = "testpage7.htm";
adsURL[8] = "testpage8.htm";
adsURL[9] = "testpage9.htm";
adsURL[10] = "testpage10.htm";
adsURL[11] = "testpage11.htm";
//and an html file where these are included.
javascript is not showing any error and also all the statements are running but the images are not visible on the page. i couldnot figure the problem. working from last 2 days.
New answer:
Some of your code had to be revised I think. I just edited this off of what I thought it was supposed to look like.
Check the new jsFiddle
I think it might be getting you closer.
Briefly, the issue was that childNodes() returns an array of elements, so you need to reference that variable as you would an array
Secondly, you didn't have all the appends that were required.
var adsURL = new Array();
adsURL[0] = "testpage0.htm";
...
adsURL[11] = "testpage11.htm";
var nextAd;
var moveNextAd = function (top) {
nextAd.style.top = top + ".px"
}; //changed this to function as variable, answer explained below
var changeBannerAd = function () {
var num = adsURL.length
var allAds = document.getElementById("bannerBox")
allAds = allAds.childNodes;
//^^^ here is what was wrong
// Child nodes returns an array of elements
// So for allAds, you should reference it with allAds[i]
for (var i = 0; i < num; i++) {
if (allAds[i].style.zIndex == 0) {
allAds[i].style.top = "-50px";
nextAd = allAds[i++];
}
}
for (var i = 0; i < num; i++) {
allAds[i].style.zIndex--;
if (allAds[i].style.zIndex < 0) allAds[i].style.zIndex = num - 1;
}
var timeDelay = 0;
for (var i = -50; i <= 0; i++) {
setTimeout((function () {
moveNextAd(" + i + ");
}()), timeDelay);
timeDelay += 15;
}
}; //changed this to function as variable too.
function addEvent(object, evName, fnName, cap) {
if (object.attachEvent) object.attachEvent("on" + evName, fnName);
else if (object.addEventListener) object.addEventListener(evName, fnName, cap);
}
function makeBannerAds() {
var bannerBox = document.createElement("div");
bannerBox.id = "bannerBox";
document.body.appendChild(bannerBox);
for (var i = 0; i < adsURL.length; i++) {
var bannerAd = document.createElement("div");
bannerAd.className = "bannerAd";
bannerAd.style.zIndex = i;
bannerAd.style.position = "absolute";
var urlLink = document.createElement("a");
urlLink.href = adsURL[i];
var bannerIndex = document.createElement("img");
bannerIndex.src = "banner" + i + ".jpg";
bannerIndex.style.width = "290px";
bannerIndex.style.height = "55px";
urlLink.appendChild(bannerIndex); //Here is the other problem
bannerAd.appendChild(urlLink); //All these weren't appended
bannerBox.appendChild(bannerAd); // to each other
}
setInterval((function () {
changeBannerAd();
}()), 10000);
}
addEvent(window, "load", makeBannerAds(), false);
Secondly, not to be picky or anything but you should probably declare the functions you pass into setInterval or setTimeout as variables rather than explicit functions or run them through an anonymous function like I have done. These two functions use a form of eval, and as we all know eval is evil, eval is evil, and eval is evil
Old answer; ignore
Question: Is your ads.js added before or after banners.js
Try adding the script tag before banners.js
I just placed the ads.js content above the banners.js script in a jsFiddle and it worked just fine for me
Check the JS Fiddle for full code at the top.

javascript abstract console logging

I want to make a function, like this.
For example:
function Logger() {
this.log = function(msg) {
console.log(msg);
}
}
And I want to use it in functions/modules etc, and that all works fine.
But the default console in my browser normally give the fileName + lineNumber.
Now when I abstract this functionality, the fileName and lineNumber is not where I put my instance.log(). Because it will say from where the console.log is being called, not the function itself.
So my question:
How can I get the correct information from where I want to use my logger?
Or give me, please, any tips to improve this functionality.
function Logger() {
this.log = console.log.bind(console);
}
I asked about this some time ago: Create shortcut to console.log() in Chrome.
Try using backtrace function like this one :
function printStackTrace() {
var callstack = [];
var isCallstackPopulated = false;
try {
i.dont.exist += 0; //doesn't exist- that's the point
} catch (e) {
if (e.stack) { //Firefox
var lines = e.stack.split('\n');
for (var i = 0, len = lines.length; i & lt; len; i++) {
if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
callstack.push(lines[i]);
}
}
//Remove call to printStackTrace()
callstack.shift();
isCallstackPopulated = true;
}
else if (window.opera & amp; & amp; e.message) { //Opera
var lines = e.message.split('\n');
for (var i = 0, len = lines.length; i & lt; len; i++) {
if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
var entry = lines[i];
//Append next line also since it has the file info
if (lines[i + 1]) {
entry += ' at ' + lines[i + 1];
i++;
}
callstack.push(entry);
}
}
//Remove call to printStackTrace()
callstack.shift();
isCallstackPopulated = true;
}
}
if (!isCallstackPopulated) { //IE and Safari
var currentFunction = arguments.callee.caller;
while (currentFunction) {
var fn = currentFunction.toString();
var fname = fn.substring(fn.indexOf( & amp; quot;
function & amp; quot;) + 8, fn.indexOf('')) || 'anonymous';
callstack.push(fname);
currentFunction = currentFunction.caller;
}
}
output(callstack);
}
function output(arr) {
//Optput however you want
alert(arr.join('\n\n'));
}
Try assigning the function:
(function () {
window.log = (console && console.log
? console.log
: function () {
// Alternative log
});
})();
Later just call log('Message') in your code.

Categories

Resources