getElementsByName('q')[0] returns undefined - javascript

I'm trying to get a textbox to enlarge when focused
The relevant html code is
<input class="tbox" name="q" type="text" />
Since tbox is a catchall for every textbox in the page, I have to work with the name.
I tried this javascript
window.onload = init();
function init()
{
var arr = new Array();
arr = document.getElementsByName("q");
var querybox = arr[0];
querybox.addEventListener('onfocus', wasclicked, false);
querybox.addEventListener('onblur', lostfocus, false);
}
function wasclicked(form)
{
form.q.style['width'] = '500px';
}
function lostfocus(form)
{
form.q.style['width'] = '276px';
}
Debug console tells me I can't use addEventListener on an undefined.
I'm not familiar with javascript, so I tried [0].value as well to no avail.

There are several different issues. First off, you need to use:
window.onload = init; // assign function reference to .onload to call later
instead of:
window.onload = init(); // calls init() immediately and assigns return value to .onload
This is a very common JS mistake. The way you have it, you are calling init() immediately (before the page has loaded) and assigning its return value to window.onload which won't work.
You want to assign a function reference to window.onload. A function reference is the name of the function WITHOUT any parens after it. Adding parens instructs the JS interpreter to execute the function NOW. Assigning just the name puts a pointer to the function into window.onload so it can be called later when the onload event fires.
You also have to fix your event handler callbacks because the form is not what is passed to them. The argument to an event handler is the Event object. The object that caused the event will be in this or event.target:
function wasclicked(e) {
this.style.width = '500px';
}
function lostfocus(e) {
this.style.width = '276px';
}
And, the event names are "blur" and "focus" so you need to change this:
querybox.addEventListener('onfocus', wasclicked, false);
querybox.addEventListener('onblur', lostfocus, flase);
to this:
querybox.addEventListener('focus', wasclicked, false);
querybox.addEventListener('blur', lostfocus, flase);
Combining everything and doing a little simplification, the whole thing should look like this:
window.onload = init;
function init() {
var querybox = document.getElementsByName("q")[0];
querybox.addEventListener('focus', wasclicked, false);
querybox.addEventListener('blur', lostfocus, false);
}
function wasclicked(e) {
this.style.width = '500px';
}
function lostfocus(e) {
this.style.width = '276px';
}

Note that onfocus is the the event handler, but the event itself is focus.
function init()
{
arr = document.getElementsByName("q");
var querybox = arr[0];
querybox.addEventListener('focus', wasclicked, false);
querybox.addEventListener('blur', lostfocus, false);
}
function wasclicked(e)
{
e.target.style.width = '500px';
}
function lostfocus(e)
{
e.target.style.width = '276px';
}
window.onload = init();
As you can see, the event itself contains the elemet so there's no need to add any other variable.
Just know that addEventHandler won't work on all browsers.

Try this:
window.onload = init();
function init()
{
var arr = document.getElementsByName("q");
var querybox = arr[0];
querybox.addEventListener('onfocus', wasclicked, false);
querybox.addEventListener('onblur', lostfocus, flase);
}
function wasclicked(form)
{
form.q.style['width'] = '500px';
}
function lostfocus(form)
{
form.q.style['width'] = '276px';
}

Related

Assign multiple event handlers to single event

I want to assign a JavaScript function to an event that already has a handler function. The new function should not change or remove (unassign) the existing function.
As an example:
I have a function called exFunction() that is already assigned to document.onmousemove. I have another function newFun() to assign to the same event. What I want to happen is when the document.onmousemove event occurs both functions are triggered.
newFun() is not a static function. It is going to be changing according to the webpage. (otherwise I can just write another function that calls both functions).
pure JavaScript only
By using addEventListener, you can apply multiple functions.
document.addEventListener('mousemove', exFunction)
document.addEventListener('mousemove', newFun)
You can also do like this
document.addEventListener("mousemove", function() {
myFunction();
someother();
});
As mentioned in other answers, you can easily assign several eventListeners to the event.
Note that the name of the function is the address of the code to execute and this address is immutable. The snippet shows what works and what doesn't.
var myDiv = document.getElementById('my-div');
function foo1(e) {
console.log('foo1');
if (e.altKey)
foo1 = foo2; //this doesn't work
};
function foo2(e) {
console.log('foo2');
if (e.shiftKey) {
myDiv.removeEventListener('click', foo2);
myDiv.addEventListener('click', foo3);
}
};
function foo3(e) {
console.log('foo3');
if (e.shiftKey) {
myDiv.removeEventListener('click', foo3);
myDiv.addEventListener('click', foo2);
}
};
//assign **addresses** of functions to eventListener
myDiv.addEventListener('click', foo1);
myDiv.addEventListener('click', foo2);
<div id="my-div" style="width:100px;height:100px;border:solid 1px"></div>
addEventListener is the right way to do this however time to time you may need to do this over the DOM element property event listeners by monkey patching.
Forgive me for partially snatching #AlexKudryashev's snippet.
var myDiv = document.getElementById('my-div'),
myBut = document.getElementById('my-button'),
f1 = e => console.log(`clicked "${e.currentTarget.id}" and f1 invoked`);
f2 = e => console.log(`clicked "${e.currentTarget.id}" and f2 invoked`);
monkeyPatch = (f1,f2) => e => (f1(e),f2(e));
myDiv.onclick = f1;
myBut.onclick = function(e){
console.log(`f2 monkey patched to f1. Click My Div to see the effect`);
myDiv.onclick = monkeyPatch(myDiv.onclick, f2);
}
<div id="my-div" style="width:100px;height:100px;border:solid 1px">My Div</div>
<button id="my-button">Monkey Patch f2</button>

Attaching onclick method to multiple canvas using a for loop

I need to add a onclick function to multiple canvas in a . I use a for loop to go through all the canvas and then add the onclick event with attachEvent.
I already tried with an eventlistener or directly adding the onclick event but nothing seems to work please let me know if you can see my mistake...
Here's my JavaScript code:
//here's the loop where the canvas get their width, height and onclick
//event.
function canvasSize() {
var canvas=document.getElementsByTagName('canvas');
var ctx;
for (var i=0;i<canvas.length;i++) {
canvas[i].width="50";
canvas[i].height="50";
ctx=canvas[i].getContext('2d');
ctx.fillRect(0,0,50,50);
ctx.fillStyle="blue";
canvas[i].attachEvent("click", onClick(this,"voitures"));
}
};
//onclick() function
function onClick(elem,theme) {
var images=preloadImages(theme);
var canvas=getElementsByTagName("canvas");
for (var i=0;i<canvas.length;i++) {
if (canvas[i]==elem) {
elem.drawImage(images[0],0,0)
}
}
};
//function where I preload every images
function preloadImages(theme) {
var tab=[];
var imageObj= new Image();
if (theme=="cars") {
tab[0]="0.jpg"
tab[1]="1.jpg"
tab[2]="2.jpg"
tab[3]="3.jpg"
tab[4]="4.jpg"
tab[5]="5.jpg"
tab[6]="6.jpg"
tab[7]="7.jpg"
tab[8]="8.jpg"
tab[9]="9.jpg"
tab[10]="10.jpg"
tab[11]="11.jpg"
tab[12]="12.jpg"
//...
}
for (var i=0;i<32;i++) {
imageObj.src=tab[i];
//imageObj.onload=alert("img "+i+" is loaded");
}
return tab;
}
}
The code crash before adding the onclick function. Hope someone can help me find my mistake.
One: attachEvent is only available in IE.
Two: DON'T name functions onClick it's a reserved global event handler.
So to fix your for loop I would change your last line to this:
for (var i=0;i<canvas.length;i++) {
var self = this;
if(window.attachEvent){
canvas[i].attachEvent("click", function(){
newNameForOnClickFunction(self, "voitures");
}, false);
}else{
canvas[i].addEventListener("click", function(){
newNameForOnClickFunction(self, "voitures");
}, false);
}
}
I'm betting that you want to pass the canvis to your next function and not a refrence to your canvasSize function. If that's the case then you should pass canvas[i] instead of this (or self in my example above)

Removing event listeners on automatically created multiple elements

I'm trying to remove event listeners from elements after they've been clicked on and although I seem to have a working solution, it's not ideal and I'm not sure why it works differently to the broken code.
Although I realise there are simpler ways of doing this, this is taken from a JS class I'm working on so need to retain some of the structure.
This relates to a previous post I made which was answered correctly (but didn't work when I expanded the example) - Removing event listeners with anonymous function calls in JavaScript.
In this example, the last created div removes the listener correctly but earlier ones don't (fiddle here - http://jsfiddle.net/richwilliamsuk/NEmbd/):
var ctnr = document.getElementById('ctnr');
var listener = null;
function removeDiv (d) {
alert('testing');
d.removeEventListener('click', listener, false);
}
function addDiv () {
var div = document.createElement('div');
div.innerHTML = 'test';
ctnr.appendChild(div);
div.addEventListener('click', (function (d) { return listener = function () { removeDiv(d); } })(div), false);
}
addDiv();
addDiv();
addDiv();
In the version I got working I create an array which holds all the listeners (fiddle here - http://jsfiddle.net/richwilliamsuk/3zZRj/):
var ctnr = document.getElementById('ctnr');
var listeners = [];
function removeDiv(d) {
alert('testing');
d.removeEventListener('click', listeners[d.id], false);
}
function addDiv() {
var div = document.createElement('div');
div.innerHTML = 'test';
ctnr.appendChild(div);
div.id = listeners.length;
div.addEventListener('click', (function(d) {
return listeners[listeners.length] = function() {
removeDiv(d);
}
})(div), false);
}
addDiv();
addDiv();
addDiv();
document.getElementById('btn').addEventListener('click', function() {
alert(listeners);
}, false);​
The final one works fine but I'm sure the listener array shouldn't be necessary. Maybe I'm worrying too much but I'd like to know the optimal solution.
you are right, you don't need an array, just hold every listener in a variable, than pass eventlistener in your remove() function,
var ctnr = document.getElementById('ctnr');
function removeDiv(d, ev) {
alert('testing');
d.removeEventListener('click', ev, false);
}
function addDiv() {
var div = document.createElement('div');
div.innerHTML = 'test';
ctnr.appendChild(div);
div.addEventListener('click', (function(d) {
var myfunc;
return myfunc = function() {
removeDiv(d, myfunc);
}
})(div), false);
}
addDiv();
addDiv();
addDiv();
document.getElementById('btn').addEventListener('click', function() {
alert(listeners);
}, false);​​
updated jsfiddle page
You have to save each and every listener if they are unequal, so you need a relation between listener and element. Since an element is represented by an object (DOM: document object model) you can add custom properties to them (although it's not recommended: Can I add arbitrary properties to DOM objects?) (demo):
var ctnr = document.getElementById('ctnr');
function removeDiv (d) {
alert('testing');
d.removeEventListener('click', d.custom_Listener , false);
}
function addDiv () {
var div = document.createElement('div');
div.innerHTML = 'test';
div.custom_Listener = function(){removeDiv(this)};
ctnr.appendChild(div);
div.addEventListener('click', div.custom_Listener , false);
}
But since your using the same listener in every div its even better not to use a separate function for every div but the same (demo):
var ctnr = document.getElementById('ctnr');
var listener = function(){
removeDiv(this);
};
function removeDiv (d) {
alert('testing');
d.style.backgroundColor = '#36f';
d.removeEventListener('click', listener, false);
}
function addDiv () {
var div = document.createElement('div');
div.innerHTML = 'test';
ctnr.appendChild(div);
div.addEventListener('click', listener , false);
}

roll-over script not working

I am trying to make a mouse roll-over. i.e when user places the pointer on the image mouse over event is triggered and the next image from the array comes over.But nothing is happening when i am running this script :
window.onload = startRollOver;
var pictures = new Array("1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","6.jpg","7.jpg","8.jpg");
var i = 0;
function startRollOver() {
document.getElementById("picture").src.onmouseover = createRollOver();
}
function createRollOver() {
if(i<=7)
return pictures[i++];
if(i>7) {
i=0;
return pictures[i];
}
}
Where am i going wrong ?
.src.onmouseover does not make much sense. You should assign a function to onmouseover so that the function gets called when the mouse moves over the element:
document.getElementById("picture").onmouseover = function() { // is executed when mouse is over element
this.src = createRollOver(); // each time it is called, change the src
};
Also, you can use a more convenient way of declaring arrays:
["1.jpg", "2.jpg", ...]
You're setting "onmouseover" on the string "src" instead of on the DOM element. You need to set the event on the DOM element.
window.onload=startRollOver;
function startRollOver() {
document.getElementById("picture").onmouseover = function (e) {
e.target.src = createRollOver();
};
}
function createRollOver() {
// ...
}

Adding onclick to div element yields "Result of expression 'document.getElementById('elem1')"[null]

is not an object" in the safari browser. The entire code is
function addLinks () {
var p0 = document.getElementById('Pic0').onclick = addLinkAction;
}
function addLinkAction () {
var el = document.getElementById('vid0');
el.style.display = "block";
el.play();
}
The functions work fine but safari continues to throw errors when the page is rendered and and on each click of the link. I'm only testing this in safari as it's a HTML5 - iPad/iPhone only media. thanks
Try this:
function addLinks () {
var p0 = document.getElementById('Pic0').onclick = function () {
var el = document.getElementById('vid0');
el.style.display = "block";
el.play();
};
}
Make sure the element exists. When you invoke addLinks do it on DOM ready or window.onload = function(){}. Alternatively, put the script before the end body tag.
assuming you call function addLinks() on document load/ready, try to add return false as last statement of this inner function
function addLinks () {
var p0 = document.getElementById('Pic0');
p0.onclick = function() {
addLinkAction();
return false;
}
}

Categories