Mingling with onclicks

20070307387

Some magical ASP.NET black box code generates an onclick attribute in an anchor to make an AJAX call. However that same anchor needs additional onclick radness – perhaps showing/hiding a div, changing an element’s class or maybe something really awesome like making the browser window shake. Like all good code, the latter event is being added with DOM scripting. But simply assigning the new magic code to the anchor’s onclick will overwrite .NET’s AJAX call. Rather than replace, it needs to be added to. Unfortunately functions don’t have a sassy concatenation operator like strings do. So it’s the long way.

This probably has a technical name and there are other coding strategies that would avoid this problem to begin with, but for the sake of example, here’s the particular problem. Start with a collection of anchors

var as = el.getElementsByTagName("a");

Then loop through them

for(var i;i<as.length;i++) {

Normally now is when each anchor would get a new onclick event

as[i].onclick = function() { //do something awesome }

But that alone would overwrite the onclick defined in the HTML source. My first attempt to use getAttribute within the new function to grab the onclick from the HTML, then run it through eval

eval(this.getAttribute("onclick"));

Internet Explorer has two problems with that: having already reassigned the onclick on the line above overrides the actual attribute and its getAttribute returns a different string than other browsers.

In order to get IE to play nice, .NET’s onclick must be captured before the new assignment and passed to the anonymous function for evaling. This can be done be adding an additional property to the anchor, assigning it the onclick, then later accessing it in the function via this.


var as = el.getElementsByTagName("a");

for(var i;i<as.length;i++) {
  as[i].og = as[i].onclick; //assigning the original onclick to a different property of the current anchor

  //the new onclick
  as[i].onclick = function() {

    //make sure og exists and in this case only need the .NET click to happen once so check for loaded class
    if(this.og && this.className!="loaded") {
      //onclick actually equals function(){ stuff } so convert to string and strip out what eval won't understand
      //regex would perhaps be nicer but I'm miserable at that
      var ogfirst = this.og.toString().split("{");
      var ogclick = ogfirst[1].split("}");
      //left with just the function as a string, eval it
      eval(ogclick[0]);
      this.className = "loaded"; //set so we don't do this on subsequent clicks
    }

    // window shaking code goes here

  }
}

Skateboards and bikes are better at nights

Skateboards and bikes are better at nights. 0 comments.


Search WayTooCrowded
The Header Should Always Point Home