Bug Tracker

Opened 13 years ago

Closed 13 years ago

Last modified 8 years ago

#999 closed bug (fixed)

ASP.Net 2.0 Page Scroll code is triggering the jQuery event handler causing jQuery to throw a JavaScript error “this.events is undefined”

Reported by: ZombieBob Owned by:
Priority: major Milestone: 1.1.3
Component: event Version: 1.1.1
Keywords: ASP.Net, this.events, Error Cc:
Blocked by: Blocking:

Description

Description: ASP.Net 2.0 makes use of an automatic resource files generation via a server side web page called WebResource.axd and this is common across the entire industry. Changing how Microsoft renders these resource files and JavaScript is unlikely to happen so it is up to the community to provide workarounds.

Im attaching a Microsoft Word .doc file with all the detials/screen prints and JavaScript debug session details in VS.Net but will add the basic text below.

BUG: ASP.Net 2.0 Page Scroll code is triggering the jQuery event handler causing jQuery to throw a JavaScript error “this.events is undefined”

Description: ASP.Net 2.0 makes use of an automatic resource files generation via a server side web page called WebResource.axd and this is common across the entire industry. Changing how Microsoft renders these resource files and JavaScript is unlikely to happen so it is up to the community to provide workarounds.

Steps to reproduce: (Sorry I had to put a patch into the jQuery code to ensure our enterprise operations here at Intel Corp so the page below will not throw the error now. If you want to schedule some time with me I can set the error condition back up or perhaps you could use Microsoft Fiddler to do an inline replace for the jQuery Script source reference.)

Step 1: Load the following webpage - http://serverconfigurator.intel.com/configure.aspx?id=1194

Step 2: Make your browser into a smaller scrolling footprint like the following screen print with images and set your scrollbar somewhere in the middle like shown below Detail Note: ASP.Net 2.0 PostBack event's are automatically triggered when you click on any any of the radio button on this web page.

Step 3: Clicking on a radio button with the screen setup in the above format causes an ASP.Net PostBack event to fire re-loading the page. When the page is loaded on a postback a call is made to WebResource.axd that load some Javascript that is used to attempt to reposition the scroll bar.

Detail Note: The page postback adds javascript code to the page to assist in repositioning the scrollbar, here is the stub of code rendered right before the closing HTML’s </body> tag. This auto-rendered script grabs the windows onload and places it in theForm.oldOnLoad.

<script type="text/javascript">
<!--

theForm.oldSubmit = theForm.submit;
theForm.submit = WebForm_SaveScrollPositionSubmit;

theForm.oldOnSubmit = theForm.onsubmit;
theForm.onsubmit = WebForm_SaveScrollPositionOnSubmit;

theForm.oldOnLoad = window.onload;
window.onload = WebForm_RestoreScrollPosition;
// -->
</script>

Detail Note: This file is referenced also referenced (http://serverconfigurator.intel.com/WebResource.axd?d=p6mYeAhud6PI4_X9tDzOXw2&amp;t=632777119425110309) which contains the following snippet of code. The BOLD item below is triggered in the code snippet

function WebForm_RestoreScrollPosition() {
362 if (__nonMSDOMBrowser) {
363 window.scrollTo(theForm.elements['__SCROLLPOSITIONX'].value, theForm.elements['__SCROLLPOSITIONY'].value);
364 }
365 else {
366 window.scrollTo(theForm.__SCROLLPOSITIONX.value, theForm.__SCROLLPOSITIONY.value);
367 }
368 if ((typeof(theForm.oldOnLoad) != "undefined") && (theForm.oldOnLoad != null)) {
369 return theForm.oldOnLoad();
370 }
371 return true;
372}

Detail Notes: Screen print of Internet Explorer JavaScript debugging session trace - Notice in the Call stack below. The Resource JavaScript supplied by “WebResource.axd” is attempting to execute the old window.onload function call. In this scripts context “this.events” has a valid value.

Detail Notes: The following screen-print shows the call-stack for jQuery right before the break occurs. Note that “this.events” in jQuery’s context is undefined. Below are a couple more screen captures showing that the jQuery handle: function(event) is getting a good parameter and event.type is populated

Detail Notes: Below are a couple more screen captures showing that the jQuery handle: function(event) is getting a good parameter and event.type is populated

[images missing]

Final Thoughts & Fix Suggestion: I am not 100% sure about jQuery’s event handling structure or the actual entry point that get triggered when the HTML in the page calls theForm.oldOnLoad() and I only had time to get to the actual point where the error was happening in jQuery. Sorry about that. You will have noticed that I had put in a try/catch originally but opted on the following single line of code change

Changed code from this -

// If no correct event was found, fail
if ( !event) return false;

to this –

// If no correct event was found, fail
if ( !event || !this.events) return false;

I am not sure that this was the best way to handle this problem but it appears to be working and the problem seems to be gone. I will know in a couple of days as we are using jQuery over somewhere between 5-10 thousand content pages for Page Voting, Page Tags retrieval and Page Comments.

Kevin Pirkl

Attachments (4)

BUG.doc (88.5 KB) - added by ZombieBob 13 years ago.
jQueryBugReportASP_Net_Native_ScrollCode_Issue
BUG_rtf.zip (83.6 KB) - added by ZombieBob 13 years ago.
rtf version of the bugs details…
dot_net_fix_Rev1373.diff (525 bytes) - added by brandon 13 years ago.
Patch for 1.1.1 event.js
dot_net_fix_Rev1423.diff (469 bytes) - added by brandon 13 years ago.
Patch for latest SVN

Download all attachments as: .zip

Change History (14)

Changed 13 years ago by ZombieBob

Attachment: BUG.doc added

jQueryBugReportASP_Net_Native_ScrollCode_Issue

comment:1 Changed 13 years ago by aheimlich

I don't know how much this will help, but events was recently changed to $events. Try downloading the latest nightly and see if that helps at all. Or, since I noticed you're using 1.0.4, try doing a Find/Replace for events -> $events. I can't really provide much more help as you don't have a demo of the issue in action (and I'm not familiar with ASP.NET).

Also, none of your attachments or images are showing up.

comment:2 in reply to:  1 Changed 13 years ago by aheimlich

Replying to aheimlich:

Also, none of your attachments or images are showing up.

Well, I got the Word doc, but non of the inline images are showing up

Changed 13 years ago by ZombieBob

Attachment: BUG_rtf.zip added

rtf version of the bugs details...

comment:3 Changed 13 years ago by ZombieBob

I placed the latest version of jQuery out on the Production server but the problem still appears and I left that latest version on our production site so you can see it. Let me know when I can put the patch back in place per the attached bug report (or other fix.)

I gather from perusing the forums that this problem has been around off and on for some persons for a while now so I hope I found a goodie for you. I know it took me hours to debug it and the write this whole thing up :)

The radio buttons in the ASPX page link above do a postback. After the postback the page Response loads back up with some extra javascript "window.onload = WebForm_RestoreScrollPosition;" which is how ASP.Net 2.0 attempt to restore the scroll position. After this method is triggered you will see the error and I think the bug report and potential fix will make sense.

One crummy gotcha that bit me in the a$$ quite a few times is something in Internet Explorer gets the WebResource.axd file from the IIS server. CGI Headers be dammned - IE appears to keep a local copy in IE cache directory and does not attempt to reload the file after it has been loaded once. Even a Ctrl+F5 did not do a forced reload of (http://serverconfigurator.intel.com/WebResource.axd?d=p6mYeAhud6PI4_X9tDzOXw2&amp;t=632777119425110309) file. I had to clear my IE cache and close and reopen the browser to see it loaded. Firefox just loads the darn thing every time so no problem there.

I use Microsoft Fiddler to see all the file loading activity and I used Visual Studio.Net with JavaScript debugging enabled to track down the error to the degree that I have. If I can find an another extra hour I can probably simplify a repeatable version of this bug and not be pointing you to the site you can see it at right now... Anyway...

Let me know if I can give you more or better details or if you still can't see the images in the attached RTF file. I can save it as HTML to my home server if need be...

Kevin Pirkl (ZombieBob at Intel.com)

comment:4 Changed 13 years ago by brandon

This is an interesting issue. jQuery isn't even used to bind any events on that page, from what I can tell. So, I'm not sure why the jQuery.handle method is even being called. We really need a dumbed down page/test case to find the issue.

comment:5 Changed 13 years ago by ZombieBob

Ok I have it down to some simple HTML that I will post here

jQuery appears to auto-bind code to the window.onload event when the jQuery script is loaded and hence when the ASP.Net 2.0 code renderer engine generates it's own code regarding scrollbar position (on a page postback event in this case) ASP.Net stores off the old window.onload and does it's work then tries to run the code as hooked by jQuery which throws the error.

Below is the boiled down version of that code with 99% of non-essentials stripped of. I imagine that lots of coders use this same pattern to play well with other window.onload handlers.

<HTML>
<HEAD>
	<title>Test Error 999</title>
	<script language="javascript" src="http://jquery.com/src/jquery-latest.js"></script>
</HEAD>
<body>

	<form name="Form1" method="post" action="configure.aspx?id=1194" id="Form1">		

<script type="text/javascript">

	// I HAVE BOILED IT DOWN TO JUST THE BASICS NOW AND OTHER THAN COMMNETS THIS WOULD ALL BE AUTOGENERATE ASP.NET 2.0 Code


	var theForm = document.forms['Form1'];
	if (!theForm) {
	    theForm = document.Form1;
	}

	function WebForm_RestoreScrollPosition() {

		// I REMOVED THE EXTRANEOUS CODE FOR BREVITY - Kevin Pirkl

		if ((typeof(theForm.oldOnLoad) != "undefined") && (theForm.oldOnLoad != null)) {
			return theForm.oldOnLoad();
		}
		return true;
	}

	alert(window.onload);  // curious <- jQuery has already hooked the load event.....

	// <-- ASP.Net 2.0 produces this code to play nice when others who have set their own onload handler
	theForm.oldOnLoad = window.onload;  

	alert( "About to Error on jQuery.cs code of -- var c = this.events[event.type];   in  -- ")
	window.onload = WebForm_RestoreScrollPosition; // <-- ASP.Net 2.0 on the postback Response tries to reposition the scrollbar.

</script>

	</form>

	</body>
</HTML>

I hope this helps. My original fix suggestion may or may not be the best but I hope it helps get you in the right direction.

comment:6 Changed 13 years ago by brandon

Resolution: wontfix
Status: newclosed

The problem is that by storing the event handler on theForm, the scope is changed from the window to theForm. Also they do not pass the original event to the handler. The fix you posted does prevent the error but it also prevents the handlers from being fired.

Since the generated JavaScript by ASP.Net changes the scope and does not pass the event object, I'm unsure how we will be able to fix this in the jQuery core.

Hopefully other libraries, frameworks and scripts do not use this technique as it completely renders the original event useless.

comment:7 Changed 13 years ago by ZombieBob

Resolution: wontfix
Status: closedreopened

Sorry to push the point.... I want to re-open this but will accept your final decision. I have 10 hours of my professional services in on this bug and would like to see it fixed for all ASP.Net developers.

I presented a very simple fix already that I don't think would cause any extraneous impact to jQuery users and would fix the problem once and for all ASP.Net coders reporting this same issue (bottom.)

Changing a single line of code within jQuery from this

// If no correct event was found, fail
if ( !event) return false;

to this

// If no correct event was found, fail
if ( !event || !this.events) return false;



fixes the problem for every ASP.Net developer and for that matter quite a few other third party frameworks likely.

I personally dont mind patching our production version of jQuery myself but I think you guys should consider it and give proper feedback if my proposed change causes issues for other jQuery users.

We at Intel Corporation have been pushing quite a few .Net teams into using jQuery and I would hate to have to entertain alternatives (5000 web pages are making use it right now.) Please contact me direct via email if you would 9-5PM PST time Intel Corporation kevin.pirkl@…

Here are others reporting the same problem but it has not been handled for. http://72.14.253.104/search?q=cache:X-mj09gTLXIJ:jquery.com/discuss/2006-September/012820/+jQuery+this.events&hl=en&ct=clnk&cd=1&gl=us&client=firefox-a http://www.nabble.com/IE6-ASP.NET-error-from-document.onload%3A-%27this.events%27-is-null-tf2356326.html#a6563200 http://www.nabble.com/Remove-from-JSON-tf2825664.html#a7887816

Sincerely

Kevin M Pirkl

comment:8 Changed 13 years ago by brandon

Thank you Kevin for all your time and effort. It has been extremely valuable in tracking down the cause of this error.

I've created to patches that I have tested in the simplified test case you provided and it works. The first patch is for jQuery Rev 1373 (1.1.1) and the second patch is for jQuery Rev 1423 (latest SVN). Just apply the patches and rebuild the src files. Let me know if I need to provide a patch for an older tag or a specific revision.

This fix has a slightly better chance of making it into the core but I'm not very fond of it. In the mean time I'll leave this bug open for others to comment on. Perhaps we can come up with a better fix.

Again, thanks for the time and effort Kevin.

Changed 13 years ago by brandon

Attachment: dot_net_fix_Rev1373.diff added

Patch for 1.1.1 event.js

Changed 13 years ago by brandon

Attachment: dot_net_fix_Rev1423.diff added

Patch for latest SVN

comment:9 Changed 13 years ago by ZombieBob

Works!

I see the general pattern here now.

1> Many re-usable component coders like to write code that is sensitive to any previously set windows.onload event in the body html tag or via javascript window.onload hooks.

2> In this case ASP.Net 2.0 injects code into the page for postback events to deals with vertical/horizontal scrollbar positioning after re-rendering the page.

3> This injected code stored off the jQuery onload hook seeing and after re-positioning the scroll bar made tried to honor the original onload event that it usurped by triggering it thus creating the error condition.

We worked the patch through about 15 or more different ASP.Net 2.0/1.0 applications and some ASP and PHP apps as well and it not does not appears to change any existing/expected behavior. Other tests included multiple per-page $.Ready event calls

Many thanks... Kevin

comment:10 Changed 13 years ago by brandon

need: Review
Resolution: fixed
Status: reopenedclosed

With the move to DOM Level 2 event handlers this is now resolved. Fixed in the latest SVN which will soon be 1.1.3.

Note: See TracTickets for help on using tickets.