How to remove onClick handler in Javascript

Game development with Board Game Arena Studio
User avatar
stefano
Posts: 89
Joined: 28 June 2011, 22:18

How to remove onClick handler in Javascript

Post by stefano »

Hello,

I can add an handle with:

Code: Select all

dojo.query( '.card' ).connect( 'onclick', this, 'onPlayCard' );
How can I remove it?
User avatar
paramesis
Posts: 374
Joined: 28 April 2020, 05:00

Re: How to remove onClick handler in Javascript

Post 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.
User avatar
Draasill
Posts: 188
Joined: 26 April 2020, 00:00

Re: How to remove onClick handler in Javascript

Post 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)
User avatar
Tisaac
Posts: 2350
Joined: 26 August 2014, 21:28

Re: How to remove onClick handler in Javascript

Post 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.
User avatar
Victoria_La
Posts: 620
Joined: 28 December 2015, 20:55

Re: How to remove onClick handler in Javascript

Post 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");
});
User avatar
Hornir91
Posts: 37
Joined: 15 October 2018, 06:39

Re: How to remove onClick handler in Javascript

Post 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.
User avatar
Tisaac
Posts: 2350
Joined: 26 August 2014, 21:28

Re: How to remove onClick handler in Javascript

Post 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.
User avatar
Victoria_La
Posts: 620
Joined: 28 December 2015, 20:55

Re: How to remove onClick handler in Javascript

Post 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)
User avatar
Tisaac
Posts: 2350
Joined: 26 August 2014, 21:28

Re: How to remove onClick handler in Javascript

Post 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.
User avatar
Hornir91
Posts: 37
Joined: 15 October 2018, 06:39

Re: How to remove onClick handler in Javascript

Post 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");
            })
        },
Post Reply

Return to “Developers”