3

I'm using Approval Tests and WatiN to test the integration of my ASP.NET MVC2 pages. WatiN launches IE to hit the given URL and then gives me the browser's html response in a variable. Then, Approval Tests allow me to compare the html response with an "approved" version of the html response. This system works great except that something (either IE or JQuery) is adding an unexpected attribute to my element.

Here's a copy of the form tag from IE's html response:

<FORM method=post action=/Account/LogOn jQuery1314030136323="2">

Notice the jQuery1314... attribute in the form element. It is always set to "2", but the name of the attribute is always different (jQuery###########). Since it's different every time, my Approval Tests fail. I need to either run a regex on the html output and remove the param with brute force, find a way to make the attribute name the same every time, or remove is altogether. Any ideas?

I'm intentionally -not- tagging this with ASP.NET because I really think this is specific to IE or JQuery.

Byron Sommardahl
  • 12,103
  • 14
  • 68
  • 126

2 Answers2

5

That's the uuid/jQuery.expando that jQuery adds to every DOM element it interacts with, to work around browser memory leaks.

Older style code waited for window.onunload to unbind Javascript data from DOM tags to prevent memory leaks. JQuery avoids this by using a simple number (like the one in your code example) in an attribute and then keeping a hashmap in Javascript of tags and numbers (which it calls the uuid).

The weird attribute name is the value of jQuery.expando, which you can search for easily in the code and see it's set to a random value each time. This is done to allow multiple copies of jQuery to coexist on the page without interfering with each other.

I'm not aware of a use case I've ever needed where I need more than one jQuery on the same page, and I suspect you don't need this functionality either - you could easily resolve this by just eliminating this feature. Modify the code to set jQuery.expando to some hard-coded value, like 'jquery', instead of a random number, and you're good to go.

Be careful not to ever use jQuery twice in the same page though! Although doing so by accident introduces a lot of other strange side effects as well (like reuse of $), so that point may be moot.

I go into a little more detail about jQuery.expando/uuid in this question: Why Doesn't JQuery Expose its UUID Functionality?

You'll notice in that write-up that the value of the attribute is random-ish - it's a counter based on how many tags have been interacted with by jQuery so far. If your code requires the attribute value to be consistent, you may still run into trouble.

Update

You'll need to modify your jquery source. For example, 1.6.2: http://code.jquery.com/jquery-1.6.2.js

Includes the following:

jQuery.extend({
    cache: {},

    // Please use with caution
    uuid: 0,

    // Unique for each copy of jQuery on the page
    // Non-digits removed to match rinlinejQuery
    expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),

You can change the expando line as follows:

    // Does not support multiple copies of jQuery on the same page!
    // 0 included to match rinlinejQuery (/jQuery\d+/)
    expando: "jQuery0",
Community
  • 1
  • 1
Chris Moschini
  • 33,398
  • 18
  • 147
  • 176
  • Can you please give me an example of how to set jQuery.expando to something like 'jquery'? – Byron Sommardahl Aug 22 '11 at 17:07
  • This was an excellent answer, but I'd rather not modify my jquery source. I opted, instead, to run a regex on my html response and manually strip out the attributes that start with 'jquery'. This question helped me accomplish that: http://stackoverflow.com/questions/7151269/how-to-strip-out-one-common-attribute-from-every-form-element-on-the-page/7151545#7151545 – Byron Sommardahl Aug 22 '11 at 19:45
  • Where is your HTML coming from? JQuery adds these attributes at run-time, client-side, to the DOM, after the page has loaded. If you view source you'll see they aren't present. So, if you're just using what the server generates you don't need a regex in the first place. If on the other hand you're using the client-side DOM, and you're modifying the HTML on the page itself, you're going to break jQuery. – Chris Moschini Aug 22 '11 at 20:09
  • I'm using WatiN to pull the html out of the client browser (IE in this case) after page load. – Byron Sommardahl Aug 22 '11 at 21:36
  • @ByronSommardahl That's gonna break as soon as you use jQuery to insert any DOM elements. You could ninja it without modifying source by setting jQuery.expando outside of it, though the timing of when you do so might be really tricky. Have not explored. – Chris Moschini Mar 05 '15 at 19:51
0

I believe it is what jQuery does internally to track all of the elements in the DOM that you have jQuery events wired up for. You might not be able to remove them without unhooking the events.

NinjaBomb
  • 745
  • 2
  • 13
  • 29