Home > Enterprise >  Proper binding of $(this) when extracting named function in .on() callback
Proper binding of $(this) when extracting named function in .on() callback

Time:09-24

I have a snippet of code like this and everything works great:

jQuery(document).ready(function ($) {
    $(document)
        .on('click', '[selector]', function(e) {
            const paramAttr = $(this).attr('data-set-param')
            $(this).addClass('some-class').attr('checked', true)
            ...
        })
})

I want to add another event handler but reuse the initial callback so I start by extracting it out to a function like so:

jQuery(document).ready(function ($) {
    $(document)
        .on('click', '[selector]', setClickHandler)

    function setClickHandler(event) {
        const paramAttr = $(this).attr('data-set-param')
        $(this).addClass('some-class').attr('checked', true)
        ...
    }
})

I tested the above and everything still works. Now, I add another event handler:

jQuery(document).ready(function ($) {
    $(document)
        .on('click', '[selector]', setClickHandler)
        .on('keypress', '[selector]', function(e) {
            if (e.keyCode === 13) {
                setClickHandler(e)
            }
        })

    function setClickHandler(event) {
        const paramAttr = $(this).attr('data-set-param')
        $(this).addClass('some-class').attr('checked', true)
        ...
    }
})

At this point, when doing an enter key press, I get errors when accessing the contenst of the $(this) variable. How do I go about doing the proper binds or calls so that $(this) can be accessed properly in the function call?

CodePudding user response:

Use .call() to pass a this context when calling a function.

jQuery(document).ready(function ($) {
    $(document)
        .on('click', '[selector]', setClickHandler)
        .on('keypress', '[selector]', function(e) {
            if (e.keyCode === 13) {
                setClickHandler.call(this, e)
            }
        })

    function setClickHandler(event) {
        const paramAttr = $(this).attr('data-set-param')
        $(this).addClass('some-class').attr('checked', true)
        ...
    }
})
  • Related