2

I have two elements which are nested and I want to make two click functions. My body tag is for a complete page and I have a button tag which is inside the body tag.

When the user clicks the button I want to add text in my input textbox. When the user clicks outside of the button, which is inside body tag I have to remove text from the textbox.

$(document).ready(function() {
  $("button").click(function() {
    alert("only button is clicked");
    $("input:text").val("Test");
  });

  $("body").click(function() {
    alert("body clicked");
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" id="setName" value="" /><br/><br/><br/>
<button>Set the value of the input field</button>

3 Answers 3

7

While it's possible to identify the clicked element in the body click handler, it would be much easier to just call stopPropagation() within the button click handler to stop the event bubbling at all:

$(document).ready(function() {
  $("button").click(function(e) {
    e.stopPropagation();
    console.log("only button is clicked");
    $("input:text").val("Test");
  });

  $("body").click(function() {
    console.log("body clicked");
    $("input:text").val(''); // add this line to remove the text
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" id="setName" value="" /><br/><br/><br/>
<button>Set the value of the input field</button>

Sign up to request clarification or add additional context in comments.

Comments

2

Rory's answer is spot-on (as usual). Another option is to just use one handler on body and use closest to figure out whether the click passed through the button en route to body, see comments:

$(document).ready(function() {
  $("body").click(function(e) {
    // Did this click pass through the button?
    if ($(e.target).closest("button").length) {
      // Yes
      alert("only button is clicked");
      $("input:text").val("Test");
    } else {
      // No
      alert("body clicked");
    }
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" id="setName" value="" /><br/><br/><br/>
<button>Set the value of the input field</button>

1 Comment

This is the correct solution instead of using e.stopPropagation() function.
0

You can track the target of whichever element clicked via event.target and then perform the requisite operation

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body class="container">   
    <input type="text" id="setName" value="" />
    <button id="samplebtn">Set the value of the input field</button>
</body>


$("body").click(function(event) {
    if (event.target.id == "samplebtn") {
        //do button related work
    } else {
        //do other stuff
    }
});

5 Comments

That's what my answer does, except this doesn't allow for the fact that button elements can have elements inside them (for instance: <button><em>Emphasized Button</em></button>). That's why I used closest. :-)
What if the button gets changed to some input type, say textbox. Will that work then?
Yes. closest starts with the element itself. If you mean would it keep working even if you didn't change its selector, then no, of course it wouldn't. Just like one relying on an id won't work if you change the id. If you make a fundamental change, you need to handle that change throughout.
DOM Manipulations are largely done on the basis of attributes in a html element. Assume of an agile methodology which totally start relying on the "type" of html element, then, I will have to make multiple changes and go through all those iterations.
In my experience, there's no basis for that statement whatsoever. Whatever. Happy coding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.