Jump to content
Larry Ullman's Book Forums

Chapter 8 Review An Pursue


Recommended Posts

in chapter 8 there is a file (events2.js) updated to use the Utilities Object. However, when linked to events.html the code does not work. It resets the form on submit.

 

The difference I found is the anonymous function called for the onload event of the window object. What I don't understand is why the events2.js doesn't work:

 

---- events2.js ----

window.onload = function() {
'use strict';
U.addEvent(U.$('theForm'), 'submit', setHandlers);
};

 

---- events.js ----

window.onload = function() {
'use strict';
U.$('theForm').onsubmit = setHandlers;
};

 

---- addEvent() ----

 addEvent: function(obj, type, fn) {
'use strict';
if (obj && obj.addEventListener) { // W3C
obj.addEventListener(type, fn, false);
} else if (obj && obj.attachEvent) { // Older IE
obj.attachEvent('on' + type, fn);
}
}, // End of addEvent() function.

Link to comment
Share on other sites

So you're saying that events.js works, but not events2.js, right?

Hmmm... the code above looks sound (although I can't test it at the moment to be sure).

I wonder if the setHandlers function being called is the problem.

In the setHandlers function, try alerting various values to the screen at various points to try and discover where the error is.

If you're using Chrome or Firefox with Firebug, try using the JS debugger tools to find the problem.

As a last point, do you have "return false" at the end of the setHandlers function?

Link to comment
Share on other sites

That is correct events.js works. Five weeks ago I didn't know what HTML was, so you will have to forgive me that I am not in the point at the book where debugging is covered, so I am not certain where to even begin, much less how. I will tell you however, that the set handlers function is the same in both events.js and events2.js. I do have return false at the end of set handlers, and the addEvent function works with my other examples. After closer examination of chapter 8, I found this interesting tidbit:

 

 

"The problem with returning false to prevent the default browser behavior is that it only works reliably when the event listener was registered using the traditional approach. For example, say events.js added the form submission event handler using the newer approach: U.addEvent( U. $(' theForm'), 'submit', setHandlers); With that code, you would see that the form’s submission would go through, meaning that the form itself would be reset (upon resubmission) and the event listeners would not be present (they would have been created, but reset upon submission)."

 

Ullman, Larry (2012-02-21). Modern Javascript: Develop and Design (p. 298). Pearson Education (US). Kindle Edition.

 

After changing the function to use preventDefault it is now working. I still don't understand why though. Perhaps you can shed some light on that for me. And if you are feeling particularly bored & giving, maybe you can explain to me why the following function accepts an object as its first argument:

 

 // for creating event listeners
addEvent: function(obj, type, fn) {
'use strict';
if (obj && obj.addEventListener) {
obj.addEventListener(type, fn, false);
} else if (obj && obj.attachEvent) {
obj.attachEvent('on' + type, fn);
}
}, // end of addEvent function

 

I really appreciate your help. It has been invaluable to my learning. Thank you again, HartleySan.

Link to comment
Share on other sites

Good show! I always use the traditional event model, so I had forgotten that you have to use the preventDefault function to suppress the default behavior of HTML elements for the newer event models.

Thank you for catching that.

 

The addEvent method in your post takes an object as the first argument because any and all "things" returned by the getElementById and getElementsByTagName methods are JS objects. That object (which corresponds to an HTML element and) that is the first argument for the addEvent method is what the event handler specified for the second argument is attached to.

 

It's a bit confusing, I know, but the getElementById and getElementsByTagName methods return a special type of JS object call a DOM object, which is defined in the JS specs. DOM objects are able to communicate with the DOM (which is a separate API from JS) in order to actually manipulate what's displayed on the screen.

 

To be a little more specific, while I don't know all the details, the DOM has hooks (i.e., special methods) built into it so that many different computer languages can interact with it (including JS). So basically, when you call, for example, the getElementById method, behind the scenes, the browser sends the getElementById string argument to the DOM via a hook, which then searches through the virtual version of the HTML document that it has access to, and returns a bunch of relevant info to JS about the corresponding element, which the browser then organizes into a JS object (called a DOM object) that can be further used to manipulate the DOM via JS. Phew!

 

Hope that makes some sense. I suppose looking at the JS specs (or I should say ECMAScript specs) and the DOM specs would offer further enlightment (as well as further confusion, most likely).

  • Upvote 1
Link to comment
Share on other sites

Ok. Thank you for responding. At first I must admit I was confused. I did as you suggested, and looked up some ECMAScript specs and read chapter 9 which covered DOM in detail and I am further enlightened, although a little intimidated by the vast amount of possibilities and the realization of just how much I don't know. Thank you again for all your help.

Link to comment
Share on other sites

 Share

×
×
  • Create New...