Page 1 of 2

How to remove onClick handler in Javascript

Posted: 20 October 2020, 15:54
by stefano
Hello,

I can add an handle with:

Code: Select all

dojo.query( '.card' ).connect( 'onclick', this, 'onPlayCard' );
How can I remove it?

Re: How to remove onClick handler in Javascript

Posted: 20 October 2020, 16:18
by paramesis
dojo connect returns a handle that you would pass as an argument to dojo.disconnect

See more info here

So in your case, you might do something like:

Code: Select all

this.click_handler = dojo.query( '.card' ).connect( 'onclick', this, 'onPlayCard' );
...
dojo.disconnect( this.click_handler );
The solution I've been exploring with a recent project is to instead connect a click handler to the entire whiteblock div the card display is in. You can determine the clicked card using the following:

Code: Select all

var card = evt.target.closest( '.card' );
if ( card != null ) {
    this.onPlayCard( evt );
}
This can be surrounded by a switch statement for the current game state and other relevant contextual information, and this way you don't have to worry about disconnecting it or creating new click handlers for each element.

Re: How to remove onClick handler in Javascript

Posted: 20 October 2020, 19:07
by Draasill
paramesis wrote: 20 October 2020, 16:18 The solution I've been exploring with a recent project is to instead connect a click handler to the entire whiteblock div the card display is in.
This is, IMO, one of the best method (and even to the whole game board, so you can later move / duplicate the buttons / elements as you wish)

Re: How to remove onClick handler in Javascript

Posted: 20 October 2020, 20:56
by Tisaac
I'm personally strongly against this because I really don't like to have my logic mixed with my events. In particular, I never connect event with the basic function but always through arrow function so I can directly gives the info I need and not rely on html content :

Code: Select all

cards.forEach( card => {
   dojo.connect("card_" + card.id, "onclick", () => this.onPlayCard(card) );
});
If you have a function 'addCard', then you are sure that every card you add also have proper event listener (and also proper tooltip for instance), so that's not really more complicated (eventhough it would be even better to use a real templating engine like vuejs to handle listeners dynamically).
I don't see why you would need to remove the event listener ? But if really needed, I use the disconnect function as paramesis explained.

Re: How to remove onClick handler in Javascript

Posted: 20 October 2020, 23:40
by Victoria_La
the parent js class has method connect and disconnect which actually store the handlers for you but it has to be one handler at a time
this.connect(element, event, handler) and this.disconnect (element, event)

disconnect will remove all handlers of given event type

Code: Select all

cards.forEach( card => {
   this.connect(card, "onclick", () => this.onPlayCard(card) );
});
...
cards.forEach( card => {
   this.disconnect(card, "onclick");
});

Re: How to remove onClick handler in Javascript

Posted: 01 March 2021, 00:11
by Hornir91
I got into similar problem. I have several cards connected to 'onclick' event. After clicking one of them, I want the rest to be disconnected. So i store all handlers in global array and after the click I disconnect them with this code:

Code: Select all

 dojo.forEach(this.clickHandlesCombat, function(handle) {
                dojo.disconnect(handle, "onclick");
            })
And there is a problem, because all cards are disappearing (all card divs and only holders are left). Does somebody know what causes the problem?

Thanks in advance.
Cheers.

Re: How to remove onClick handler in Javascript

Posted: 01 March 2021, 10:17
by Tisaac
Hornir91 wrote: 01 March 2021, 00:11 I got into similar problem. I have several cards connected to 'onclick' event. After clicking one of them, I want the rest to be disconnected. So i store all handlers in global array and after the click I disconnect them with this code:

Code: Select all

 dojo.forEach(this.clickHandlesCombat, function(handle) {
                dojo.disconnect(handle, "onclick");
            })
And there is a problem, because all cards are disappearing (all card divs and only holders are left). Does somebody know what causes the problem?

Thanks in advance.
Cheers.
Well you definitively needs to post more code as this behaviour is clearly not caused by these lines of code.

Re: How to remove onClick handler in Javascript

Posted: 01 March 2021, 14:44
by Victoria_La
dojo.disconnect jave only one parameter -handle,
Why you are using dojo.forEach, its the this.clickHandlesCombat query results? Or what is that?
This is my code in sharecode project that does similar thing

Code: Select all

		addActiveSlotQuery: function(query, handler) {
			if (typeof handler == 'string')
				handler = this[handler];
			var superhandler = (event) => {
				if (handler(event)) {
		        	        dojo.query(query).forEach((node) => {
			        		this.disconnect(node, 'click');
		                 	});
				}
			};
			dojo.query(query).forEach((node) => {
			            this.connect(node, 'click', superhandler);
			});
		},
And you call it with query
this.addActiveSlotQuery(".something > .foo", (even)=>{...; return true;});

I skipped some code that also add classes to these (one class to make active highlight and class to mark it as temp node to clean up
in case user did not click on anything)

Re: How to remove onClick handler in Javascript

Posted: 01 March 2021, 15:58
by Tisaac
Victoria_La wrote: 01 March 2021, 14:44 dojo.disconnect jave only one parameter -handle,
Why you are using dojo.forEach, its the this.clickHandlesCombat query results? Or what is that?
This is my code in sharecode project that does similar thing

Code: Select all

		addActiveSlotQuery: function(query, handler) {
			if (typeof handler == 'string')
				handler = this[handler];
			var superhandler = (event) => {
				if (handler(event)) {
		        	        dojo.query(query).forEach((node) => {
			        		this.disconnect(node, 'click');
		                 	});
				}
			};
			dojo.query(query).forEach((node) => {
			            this.connect(node, 'click', superhandler);
			});
		},
And you call it with query
this.addActiveSlotQuery(".something > .foo", (even)=>{...; return true;});

I skipped some code that also add classes to these (one class to make active highlight and class to mark it as temp node to clean up
in case user did not click on anything)
I think dojo.forEach is a polyfill for back when [].forEach was not supported by most browsers.
So it acts as if you do a foreach on the first argument with the second argument being applied.

Re: How to remove onClick handler in Javascript

Posted: 02 March 2021, 21:53
by Hornir91
First I'm creating empty array in the constructor:

Code: Select all

constructor: function(){
              
            // Here, you can init the global variables of your user interface
            // Example:
            // this.myGlobalValue = 0;

            this.clickHandlesCombat = [];

        },
Then I'm pushing my nodes to this array when connecting the event to the queries results (dojo.connect returns nodes).

Code: Select all

for (i = 1; i <= 4; i ++) {
                 this.clickHandlesCombat.push(dojo.query("#combat_card_" + i).connect("onclick", dojo.hitch(this, "onClickCombatCard")));
                 dojo.addClass("combat_card_" + i, "can_play");
                            }
Then after doing ajax call through OnClickCombatCard I'm processing the notification with showSpiedCard, which is described below:

Code: Select all

showSpiedCard: function(card_nbr) {
            this.setClientState('client_PlayerSpyCard', {
                "descriptionmyturn": "",
            });
            var card = dojo.query('#combat_card_' + card_nbr);
            dojo.addClass(card[0], "combat_card_flip_1");

            dojo.forEach(this.clickHandlesCombat, function(handle) {
                dojo.disconnect(handle, "onclick");
            })
        },