0

Adding these two buttons using greasemonkey. I've tried reversing the order and it's always the 2nd added button that works. The other button will not fire the onclick event.

// Add the click to chat button
mydiv             = document.getElementById("optionalJobinfoData");
var btn           = document.createElement("input");
btn.type          = 'button';
btn.value         = 'Click to Chat';
btn.onclick       = function() { window.open(chatURL); };
mydiv.innerHTML  += "<i>Notify Dispatch</i><br><i>(stuck on job)</i>&nbsp;&nbsp;";
mydiv.appendChild(btn);

// Credentials button
mydiv             = document.getElementById("optionalJobinfoData");
btn               = document.createElement("input");
btn.type          = 'button';
btn.value         = 'Credentials';
btn.onclick       = function() { window.open(credsURL); };
mydiv.innerHTML  += "<br><br><i>DSL Credentials</i> ";
mydiv.appendChild(btn);
nathan hayfield
  • 2,627
  • 1
  • 17
  • 28
Cameron Darlington
  • 355
  • 2
  • 7
  • 14
  • 2
    `element.onclick` hardly works, use `addEventListener()` instead. Please check [this article](http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Getting_Started#Pitfall_.232:_Event_Handlers) – Teemu Feb 08 '13 at 18:28
  • @Teemu, you are correct (also onclick is poor practice in *any* case), but sadly, it will work *sometimes* in Greasemonkey 1.0 or greater. That is until the sandbox mode changes and the script breaks. In the userscript case, it's an example of "Time bomb" coding. It may appear to be fine for a while but, in the end, it gets you. – Brock Adams Feb 08 '13 at 22:15
  • @BrockAdams Well... actually you taught this to me earlier today [here](http://stackoverflow.com/q/14767768/1169519) : ). – Teemu Feb 08 '13 at 22:29

3 Answers3

2

the problem is in doing the mydiv.innerHTML += ...

it is similar to the answer here. Manipulating innerHTML removes the event handler of a child element?

Community
  • 1
  • 1
Al W
  • 7,539
  • 1
  • 19
  • 40
1
// Add the click to chat button
mydiv             = document.getElementById("optionalJobinfoData");
var btn           = document.createElement("input");
btn.type          = 'button';
btn.id            = 'openChat';
btn.value         = 'Click to Chat';
mydiv.innerHTML  += "<i>Notify Dispatch</i><br><i>(stuck on job)</i>&nbsp;&nbsp;";
mydiv.appendChild(btn);

// Credentials button
mydiv             = document.getElementById("optionalJobinfoData");
btn               = document.createElement("input");
btn.type          = 'button';
btn.value         = 'Credentials';
btn.id            = 'openCreds';
mydiv.innerHTML  += "<br><br><i>DSL Credentials</i> ";
mydiv.appendChild(btn);

document.getElementById("openCreds").onclick = function() { window.open(credsURL); };
document.getElementById("openChat").onclick = function() { window.open(chatURL); };

Above should work fine. Problem is that innerHTML += basically recreate objects. And pointer to onclick function handler is lost because of that (type, value etc. are parts of HTML, but innerHTML can't get pointer to a function for onclick)

Viktor S.
  • 12,736
  • 1
  • 27
  • 52
1

The following line is causing the problem:

mydiv.innerHTML  += "<br><br><i>DSL Credentials</i> ";

It is the same as doing this:

var oldHTML = mydiv.innerHTML;
var newHTML = oldHTML + "<br><br><i>DSL Credentials</i> ";

// This destroys everything inside the div and re-creates it based on the innerHTML.
mydiv.innerHTML = newHTML;

It is basically destroying any elements inside the div and re-creating them based on the html source code. However, the onclick code isn't contained in the innerHTML.