Ilan Biala
Ilan Biala

Reputation: 3419

Pass in element from one listener into nested listener

When a button is clicked a listener fires and a modal opens, and I need to get the info from the button clicked to be passed into the listeners that fire when stuff happens inside the modal.

My JavaScript:

$('li.tab').on('click', 'span.edit-tab', function() {
    var elem = $(this);
    var tabName = elem.parent().text();
    tabName = tabName.replace(/\s*$/g, '');
    $('#tab-name').val(tabName);
    $('#tab-name').on('keypress', function(elem) {
        var appendedSpan = '';
        appendedSpan += '  <span class="edit-tab glyphicon glyphicon-pencil" ';
        appendedSpan += 'data-toggle="modal" data-target="#edit-tab-modal"></span>';
        var newName = $(this).val() + appendedSpan;
        el.parent().html(newName);
    });
});

I'm trying to pass in the element that triggered the modal to be passed into the listener of an input, but no matter what I try to pass in, the variable elem is the jQuery object for #tab-name, not for span.edit-tab. Any thoughts?

Upvotes: 2

Views: 5748

Answers (2)

JohnDoe
JohnDoe

Reputation: 545

Another solution for this, could be to add what you need as an attribute to your event target.

The code snippet below illustrates how a "mousemove" event only is trickered, when a "mousedown" event occurs. To accomplish this, we need to store the function, so that it can later be removed.

If we were to handle this as the answer above proposes, we would have to store the result as a global variable. Instead a suggestion is to add the value to the html target. This is illustrated in the following code snippet, where I needed the initial "mousedown" position, as well as the "mouseup" position.

canvas.addEventListener("mousedown", down => {
    down.target.posX = down.layerX;
    this.addEventListener("mousemove", mouseDownAndMouseMove);
});

canvas.addEventListener("click", e => {
    this.removeEventListener("mousemove", mouseDownAndMouseMove);
});

const mouseDownAndMouseMove = move => {
    console.log("initial click pos: ", move.target.posX);
    console.log("new move pos: ", move.layerX);
};

Upvotes: 0

Karol
Karol

Reputation: 8053

I think the only thing you need is to save eventData and $popupTriggerElem outside the keypress context:

$('.popupTrigger').on('click', function(popupEventData) {
    var $popupTriggerElem = $(this);
    $('#tab-name').on('keypress', function(tabEventData) {
        var $tabElem = $(this);
        //now you can use all 4 variables:
        console.log(popupEventData);
        console.log($popupTriggerElem);
        console.log(tabEventData);
        console.log($tabElem);
    });
});

This way you have access to: - element which triggered click event, - click event data - element which triggered keypress event - keypress event data

It's JS's awesomness that each parent context for any function/object you're currently in is kept till the function/object will be removed from memory.

EDIT:

As you can see in @Wynand comment this behavior is based on closures. More in MDN docs.

Upvotes: 4

Related Questions