0

I'm encountering a typical situation while accessing the innerHTML property using jQuery. I've fetched the target button using the jQuery attribute selector.

Below is the snippet of jQuery attribute selector.

jQuery('button[type="button"][class="btn btn-primary"]').each(function () {
            var btn = jQuery(this);
            console.log(btn);
            if (btn[0].innerHTML === "OK") {
                console.log("ok");
                jQuery(this).click();
            }
});

Following is the screenshot of the console log of the target button. It's innerHTML property is set to OK. button_log_snippet

Following is the screenshot of the value of the innerHTML while debugging the target button object. In this case the value is "".

button_debug_snippet

Ideally, the values of the innerHTML should be the same for both the cases.

EDIT Why does this behavior differ that the ideal one? For both of the cases, the value of the innerHTML should be the same.

Also, there were multiple buttons. I have taken screenshots of different buttons. Thus their ID's are different. But still, the behavior is same.

mark42inbound
  • 364
  • 1
  • 4
  • 19
  • It looks like they are not the same element: `btn != btn[0]`? – Joel Harkes Mar 27 '18 at 14:46
  • 1
    And your question is? This isn't the Google Chrome bug request system. – freedomn-m Mar 27 '18 at 14:47
  • The two buttons aren't the same, they have different `id` (the line above the one you have highlighted). Perhaps you could crate an [mcve] which shows the issue? I'd image it would just be `` and I'd suspect it would not reproduce the issue. – freedomn-m Mar 27 '18 at 14:50
  • @freedomn-m, there's no issue with the Chrome browser. But instead of describing the issue I've posted the screenshot. – mark42inbound Mar 27 '18 at 14:54
  • Your description is fine (text+images) - just that there's no actual question here. I believe you got here by clicking the **Ask Question** button, so maybe you'd like to... ask a question? :) – freedomn-m Mar 27 '18 at 15:00
  • Have a go in this fiddle and see if it does the same: https://jsfiddle.net/fs3x14u1/1/ – freedomn-m Mar 27 '18 at 15:03
  • @freedomn-m, the question is, why does this behavior differ that the ideal one. For both of the cases the value of the `innerHTML` should be the same. – mark42inbound Mar 27 '18 at 15:03
  • Ok - add that to the question... but the answer is that: they are not the same button - look at the ID value in your 2 screenshots. – freedomn-m Mar 27 '18 at 15:03
  • Yeah, there were multiple buttons, and I might have taken the screenshot of different buttons. Sorry about that, but still the observations are the same. – mark42inbound Mar 27 '18 at 15:05
  • I'll be surprised if anyone can reproduce this - you have some unknown html and you're providing screenshots for different buttons claiming that's causing the problem. We'd like to help, but you're not giving us enough to go on. Can you *reproduce* this with some other code? Maybe update the fiddle above? Otherwise it's just hearsay. – freedomn-m Mar 27 '18 at 15:09
  • @freedom-m, I'll update the question will more code :). – mark42inbound Mar 27 '18 at 15:20
  • 1
    i am note sure if it's the same issue of this question but this link may help you: https://stackoverflow.com/questions/24175017/google-chrome-console-log-inconsistency-with-objects-and-arrays – LPZadkiel Mar 27 '18 at 15:21
  • basically, when you open the console to see an printed object, the console look after him as his final state (or the state that he has at the moment you look after him on the console), not the state when it was printed, this is a problem of `console.log` – LPZadkiel Mar 27 '18 at 15:26
  • @LPZadkiel, definitely there's inconsistency between the logging and the debug value. Thanks, your link to the question helped. But now the question is, how do I access the actual value in the code(in debug too)? – mark42inbound Mar 27 '18 at 15:52

1 Answers1

0

Try something like this.

function SomeEvent($ele) {
  alert($ele.html());
  return false;
}

function invokeBtnEvents() {
  $("[data-action=some-event]").off(); // clear old events
  $("[data-action=some-event]").on("click", function() {
    var $this = $(this);
    return SomeEvent($this);
  }) // define event(s)
  return false;
}
$(document).ready(function() {
  invokeBtnEvents();
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="row">
    <div class="col-12">
      <br />
      <button data-action="some-event" class="btn btn-primary">Button 1</button>
      <button data-action="some-event" class="btn btn-primary">Button 2</button>
      <button data-action="some-event" class="btn btn-primary">Button 3</button>
      <button data-action="some-event" class="btn btn-primary">Button 4</button>
    </div>
  </div>
</div>

Your issue

What you are doing that I think is your main issue is the $.each() method.

Store the buttons in a variable,

let $button = $("button"); // this returns an array of all the buttons on the DOM

You can then use the $.each() method to get the clicked element

$.each($button, function(index, btn){
    const $this = $(btn);
    $this.off();
    $this.click(function(){someEvent($this)});
});

I would not invoke button clicks like this because every time you click a button, this each loop gets ran. It will then send all of the buttons to that action unless you parse by an ID or something (you are using the innerText).

If you use the code in my snippet, only the clicked button will be triggered.

An alternative approach to my first snippet is using something like a dispatcher.

function DoActionOneClick($ele){
  alert("Action 1 " + $ele.html());
}

function DoDefaultClick($ele){
  alert("Default Action " + $ele.html());
}

function DispatchEvent(action, $ele){
  switch(action){
    case "some-event-1":
      DoActionOneClick($ele);
      break;
    default:
      DoDefaultClick($ele);
      break;
  }
}

function invokeActions(){
  $("[data-action]").off();
  $("[data-action]").on("click", function(){
    // get this
    var $this = $(this);
    // get action
    var action = $this.data().action;
    DispatchEvent(action, $this);
  });
}

$(document).ready(function(){
  invokeActions();
})
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="row">
    <div class="col-12">
      <br />
      <button data-action="some-event-1" class="btn btn-primary">Button 1</button>
      <button data-action="some-event-2" class="btn btn-primary">Button 2</button>
      <button data-action="some-event-2" class="btn btn-primary">Button 3</button>
      <button data-action="some-event-2" class="btn btn-primary">Button 4</button>
    </div>
  </div>
</div>
Christian4423
  • 1,746
  • 2
  • 15
  • 25