0

After clicking in this button:

var option_btn = document.querySelectorAll('[class*="sp_choice_type"]')[1]

the following button will be available in the web:

var refuse = document.querySelector('[class*="priv-reject-btn"]')[0]

but as is not available before clicking there, with the following piece of code won't work:

var option_btn = document.querySelectorAll('[class*="sp_choice_type"]')[1]
option_btn.addEventListener('click', ()=>{
    setTimeout(()=>{
        var refuse = document.querySelector('[class*="priv-reject-btn"]')[0];
        refuse.addEventListener('click',() =>{
            console.log("Eureka")
    })
    }, 5000)
})

I've also tried with some Promises, but didn't work either.

The case is in the site zonebourse.com with the button Option from the botton disclaimer and "Tout refuser" that is triggered just after clicking the Option

error404
  • 63
  • 1
  • 10
  • Have you tried setting a breakpoint in your code to se if `refuse` FOR SURE isn't getting the proper dome element? – TKoL Dec 16 '19 at 17:54
  • 2
    `querySelector` doesn't return a list, you shouldn't index it. – Barmar Dec 16 '19 at 17:54
  • So it should either be just `document.querySelector(...)` or `document.querySelectorAll(...)[0]`. – Barmar Dec 16 '19 at 17:56
  • @Barmar he is using querySelectorAll which does in fact return a list – huhnmonster Dec 16 '19 at 17:57
  • @huhnmonster Not on the line that sets `refuse`. – Barmar Dec 16 '19 at 17:58
  • Oh yeah, missed that. You are completely right – huhnmonster Dec 16 '19 at 17:59
  • @Barmar var refuse = document.querySelectorAll('[class*="priv-reject-btn"]')[0]; will also work as soon as the button refuse appears. – error404 Dec 16 '19 at 18:00
  • @error404 That's what I'm saying -- it will work if you use `querySelectorAll`. You should be getting an error with just `querySelector`. – Barmar Dec 16 '19 at 18:24
  • Please post a [mcve] here. I can't find the button you're talking about on the remote site. – Barmar Dec 16 '19 at 18:26
  • First of all: thanks a lot for taking a look at it. The first one that is easy to grab is this: https://www.screencast.com/t/4KeoEsvK and the second one that I can't grab is this one: https://www.screencast.com/t/GPFPzkGflV1j everything in the web zonebourse.com You can probably see the buttons if you open the site in the incognito mode – error404 Dec 16 '19 at 18:36

1 Answers1

0

Without seeing a working example of the problem you are facing it's hard to say for sure what the issue is. It seems that you are attempting to add a new button (Button B) to the page when the user clicks another button (Button A) and take an action when Button B is pressed. With that in mind here is an example of adding a button to the page and taking an action when that new button is clicked. The code is commented but let me know if you have any questions or if anything isn't clear and I'll improve my answer.

// find all option buttons
var options = document.querySelectorAll('.option');
// loop over all option buttons
[...options].forEach((opt) => {
  //  wire event handler for click
  opt.addEventListener('click', (e) => {
    // check if we have already added the button
    if (!e.target.actionButton) {
      // return a promise instead of setTimeout for better async
      return new Promise((resolve, reject) => {
        // create the new button
        var btn = document.createElement("button");
        // pull out the option attribute to make it easier to reference later
        var optionAttr = e.target.getAttribute('data-option')
        // store the option for this button
        btn.setAttribute('data-option', optionAttr);
        // wire the click handler for this button
        btn.addEventListener('click', (ev) => {
          // get the option
          var option = ev.target.getAttribute('data-option');
          // just log for now
          console.log(`you clicked ${option}`)
        });
        // set the text of the button
        btn.innerHTML = `Action Button ${optionAttr}`;
        // store a reference to the action button on the option button
        e.target.actionButton = btn;
        // append the new action button to the action button container
        document.querySelector('#buttons').append(btn);
        // resolve the promise
        resolve();
      });
    }
  })
});
button {
  display: inline-block;
  margin: .5em;
  padding: .5em;
}

#buttons button {
  display: inline;
  margin: .5em;
  padding: .5em;
}
<button class="option" data-option="1">
Option 1
</button>
<button class="option" data-option="2">
Option 2
</button>
<div id="buttons">

</div>
Adam H
  • 1,750
  • 1
  • 9
  • 24
  • Thanks a lot for your explanation and for the feedback of how I should explain the problem. Here is the thing: There are two buttons that I want to interact with, exactly, but there is something tricky: The second button is not defined in the code, it will just appear after clicking in the first one, therefore when you try to grab it with some code, you will get an error. – error404 Dec 16 '19 at 20:47
  • I'm not sure I understand your scenario; When you say your second button are you talking about Button B (action button in the example) or another Button A (option button in my example)? – Adam H Dec 16 '19 at 21:36
  • after clicking on this button: https://www.screencast.com/t/4KeoEsvK this button will be available inside an iframe http://www.screencast.com/t/GPFPzkGflV1j The code of the iframe will be triggered after clicking on the first button, therefore is imposible to grab the second button. – error404 Dec 16 '19 at 21:45
  • Ok, this is a totally different problem than I thought you were having. it's not that the second button doesn't exist in the DOM the problem is that the second button is going to be rendered in an IFrame which is loaded when the user clicks the first button, correct? – Adam H Dec 16 '19 at 22:17
  • 1
    If that is the case then you are going to want to look at the [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) pattern to communicate between the IFrame and the Host. [Here](https://stackoverflow.com/questions/8822907/html5-cross-browser-iframe-postmessage-child-to-parent) is a SO post asking about implementation details if the MDN article isn't enough. – Adam H Dec 16 '19 at 22:20
  • I don't know if it's going to work, but thanks a lot for the tip. I am reading it right now :-)))))) – error404 Dec 17 '19 at 10:01