简体   繁体   中英

Why doesn't 'this' keyword work in following html code?

I want an alert with "button text"

this doesn't work:

<button onclick="fun()">button text</button>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script>
    function fun(){
        alert($(this).html()); //I've also tried $(this).val() and $(this).text()
    }
</script>

but following works fine:

<script>
    function fun(){
        alert("some plain text");
    }
</script>

The this you're trying to log is the Window object, on which you can't use innerHTML . Instead, pass the context of the button element.

 function fun(context) { alert($(context).html()); } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button onclick="fun(this)">button text</button> 

I realize you've already accepted an answer, but none of the answers you received addressed your question. Please consider the following:

The HTML attribute for the on- type handlers were designed from the beginning to take raw JavaScript code and wrap that code into a function. That function is provided with the event object and the context set to the keyword this as the element receiving the event. So the first button in my solution below is the proper way to accomplish what you were attempting to do.

Ref: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers#Event_handler's_parameters_this_binding_and_the_return_value

The same can be accomplished by setting the DOM Element's on- event property to the function name. This is seen in the second button example. Note that when the DOM property is used, the event is passed and the context set the DOM element too.

Now, the reason something like onclick="fun(this)" and its variants work in these answers, is because that is being wrapped inside a function which is executed with the this keyword set the context of the DOM element (just as described above). So it is a function calling a function and passing the current context - and an anti-pattern.

That should really answer your question.

 document.querySelector('#otherButton').onclick = fun; function fun() { alert($(this).html()); } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button onclick="alert($(this).html());">button text</button> <button id="otherButton">other button</button> 

The following works:

<button onclick="fun(this)">button text</button>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script>
    function fun(myButton){
        alert($(myButton).html()); //I've also tried $(this).val() and $(this).text()
    }
</script>

Within fun , this will not be your button, because fun is not called on the button.

The following also works:

<button onclick="fun.apply(this)">button text</button>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script>
    function fun(){
        alert($(this).html()); //I've also tried $(this).val() and $(this).text()
    }
</script>

This code causes this to be defined in the manner you tried to use it.

Because you call fun() as a free function but not as a method. Being called as a function the fun() receives this set to global namespace.

In order to call fun with this set to what you want you shall be specific, for example like this:

 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button onclick="fun.call(this)">button text</button> <script> function fun(){ alert($(this).html()); //I've also tried $(this).val() and $(this).text() } </script> 

Using a native js event handler does not give the this context for jquery. The dom element that you clicked on is available through

function fun (e) {
  let el = e.target // currentTarget, etc.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM