views:

49

answers:

3

I'd like to use JavaScript only (no jQuery) to replace an inline onmenuclick event handler generated by a third party control with my own.

The custom control has added the following HTML to the page:

<ie:menuitem
  menugroupid="200"
  description="Create a site for a team or project."
  text="New Site"
  onmenuclick="if (LaunchCreateHandler('Site')) { STSNavigate('\u002fsites\u002fsd\u002f_layouts/newsbweb.aspx') }"
  iconsrc="/_layouts/images/newweb32.png" type="option" id="zz4_MenuItem_CreateSite"></ie:menuitem>

I'm trying to replace the onmenuclick handler with:

var createSiteMenuItem = document.getElementById('zz4_MenuItem_CreateSite');
if (createSiteMenuItem)
    createSiteMenuItem.onmenuclick = function () { alert('Hello!'); }

The original handler still fires! I'm making sure the script runs after the document has loaded.

Is this the correct approach?

+1  A: 

The trouble is that directly assigning to onmenuclick is unreliable and non-standard. You need to use attachEvent() (IE) or addEventListener() (everyone else).

Edit:

As explained below, the actual problem was that in Javascript, element attributes are case-sensitive, despite the HTML, which isn't. So any reference to the menu click event in Javascript has to refer to it as "onMenuClick".

staticsan
If I use `attachEvent`/`addEventListener`, is there a way I can remove the existing `onmenuclick` so it never fires?
Alex Angas
Yes. `removeEventListener()/detachEvent()`
staticsan
In this case, I don't think that's the problem. The onmenuclick should replace the old event handler. Is the alert() popping up? Cuz, if not, it may be that createSiteMenuItem is still null or undefined.
Azmisov
Please have a read of my answer to this question and see if you think I have this right. Your first line is correct but I don't think the solution is. Thanks for pointing me in the right direction!
Alex Angas
Well spotted! I had, in fact, been tripped up that very problem recently, but since I'm in the habit of being case-correct whatever the language and didn't correlate it with this problem. I shall edit my answer to make it clear for people who later come across this question.
staticsan
Thanks that's great! I'm getting that "we all learned something" fuzzy feeling now. ;-)
Alex Angas
A: 

The id may be generated dynamically. So one time it is 'zz4_MenuItem_CreateSite' the next time it is something else. Way to check: observe the html source on multiple downloads, see if the ids vary.

This msdn article seems to point in that direction.

Suggestion: wrap the menu items in a div with an id that you assign. Then walk the dom tree within your div to find the right element to modify.

Larry K
I will need to implement something like this because the ID may change. However for this test/example/prototype/whatever it is not changing.
Alex Angas
A: 

I've marked staticsan's answer as correct - onmenuclick is non-standard and that's why the problem is occurring. However the original resolution suggested wasn't quite right. This has since been corrected, but here's the back story for completeness...


I debugged this in Visual Studio and could see that onmenuclick is recognised as an expando instead of an event. This means attachEvent and addEventListener do not apply and fail when used.

VS debugger of this code

The resolution was far more simple. I changed the casing to that shown in the Visual Studio debugger so it read onMenuClick instead of onmenuclick. The "faux-event" now fired correctly.

Alex Angas