I'm using Highcharts and I want to trigger some events when the user clicks on the labels of the chart. It works fine as long as I do not redraw.
When I use chart.redraw() the click event is no longer triggered
Here is a fiddle : https://jsfiddle.net/AJeantet/28oebumb/3/
Does anyone know a workaround ?
Thanks,
Adrien
The current issue is that you're attaching event handlers to DOM nodes that are destroyed when the chart is redrawn.
Change
$('.label_wrapper').click(function() {
console.log('Still working...');
});
to
$(document).on('click','.label_wrapper', function() {
console.log('Still working...');
});
The handlers will be attached to the document instead of the nodes that are being redrawn, meaning that the event handler will never be destroyed.
See the updated fiddle here.
Related
Update: I tried a suggestion by #newmount however, if I call fireEvent('blur') then the focus of the trigger isn't fired by any keyboard action. (It resumes once there is a mouse click)
To be honest the triggerfield doesn't fire blur in a certain situation.
From within the focus event if I have a reference to another field and do field.focus() the blur of the current field doesn't fire. What's worse is it fires later if I click anywhere else.
Below is code and steps to reproduce:
Ext.onReady(function() {
Ext.define('Ext.ux.CustomTrigger', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.customtrigger',
labelStyle: 'white-space: nowrap',
initComponent : function() {
this.on("focus", function() {
console.log("Trigger focused");
//the problem point.
//I do some processing here and then
//in some case I do the following:
Ext.getCmp('some_field').focus();
//when this is called the BLUR of this trigger field isn't fired.
});
this.on("blur", function() {
console.log("Trigger blurred");
});
this.callParent();
}
});
//end of onReady
});
Here is a live fiddle : http://jsfiddle.net/sq37s/
To Reproduce:
Click into the first name field
Hit tab, it will jump into the trigger and then jump into the mid init field.
The console at this point will not show a Trigger blurred
Now click anywhere in the panel and you'll see Trigger blurred.
This behavior is causing some very unexpected issues in our application, this is something so trivial we based assumptions on the fact that something like this will work.
I would love:
Any suggestions to work around this, perhaps pure javascript
Any hope of getting the extjs guys to fix this?
When the focus gets changed programmatically, the event may not get fired (think events gets fired only on user-action). One workaround is to fire that event programmatically while changing focus
this.on("focus", function(e) {
console.log("Trigger focused");
if (someConditionToChangeFocus){
e.fireEvent('blur'); //Fires the blur event
Ext.getCmp('some_field').focus();
}
});
[Edit]
Another approach is to use FocusManager's beforecomponentfocus event, fiddle here: https://fiddle.sencha.com/#fiddle/3mq
I'm having an issue where when I try to zoom in on a certain area of my graph that is continuously updating the plotselected event fires off numerous times instead of just once. I've slowed down the update rate in the attached jsfiddle significantly so that you aren't overwhelmed with alert messages to show the multiple plotselected events fired off. With a quicker refresh rate you could be stuck with 50+ of those messages. Anyways, is there a way to only fire off that event handler for the last event in the chain that's created after selecting the area? Suspect code in question (this works fine in static mode):
$("#overview").on("plotselected", function (event, ranges) {
alert(ranges.xaxis.from+','+ranges.xaxis.to);
plot.setSelection({
xaxis: {from:ranges.xaxis.from,to:ranges.xaxis.to}
});
});
full jsfiddle example: http://jsfiddle.net/grkblood13/6TG5a/
You are attaching the plotselected event handler to your plot div every time you call plotData. These are cumulative!
So, simply remove the $("#overview").on("plotselected" call outside that function.
Updated fiddle.
So I used this totally awesome tool called Visual Event, which shows all the event handlers bound to an object - and I noticed that every time I clicked or played around with my object and checked the list of event handlers bound to it, there were and more every time. My problem is this one: console.trace or stack trace to pinpiont the source of a bug in javascript? After using Visual Event and someone else's suggestion, I'm thinking my problem is that I'm probably binding the same handlers to the same events over and over again. Is there a way to unbind things regularly?
My application has a bunch of plugins connect to dynamically created divs. These divs can be resized and moved around the place. The application is a kind of editor, so users arrange these divs (which contain either images or text) in any design they like. If the user clicks on a div, it becomes "activated", while all other divs on the page get "deactivated". I have a bunch of related plugins, like activateTextBox, initTextBox, deactivateTextBox, readyTextBox, and so on. Whenever a div is first created, the init plugin is called once, just the first time after creation, like so:
$(mydiv).initTextBox();
But readyTextBox and activateTextBox and deactivateTextBox are called often, depending on other user events.
In init, I first use bind things like resizable() and draggable(), then I make the box "ready" for use
$.fn.extend({
initTextBox: function(){
return this.each(function() {
// lots of code that's irrelevant to this question
$this.mouseenter(function(){
if(!$this.hasClass('activated'))
$this.readyTextBox();
}
$this.mouseleave(function(){
if($this.hasClass('ready')){
$this.deactivateTextBox();
$this.click(function(e){
e.preventDefault();
});
}
});
});
});
Here's a simplified summary version of the readyTextBox plugin:
(function($){
$.fn.extend({
readyTextBox: function(){
return this.each(function() {
// lots of code that's irrelevant to this question
$this.resizable({ handles: 'all', alsoResize: img_id});
$this.draggable('enable');
$this.on( "dragstop", function( event, ui )
{/* some function */ });
$this.on("resizestop", function( event, ui ){ /* another function */ });
// and so on
});
Then there's activateTextBox():
$.fn.extend({
activateTextBox: function(){
return this.each(function() {
// lots of code that's irrelevant to this question
$this.resizable('option','disabled',true); //switch of resize & drag
$this.draggable('option', 'disabled', true);
});
Then deactivate, where I turn on draggable and resizable again, using the code:
$this.draggable('enable'); $this.resizable('option','disabled',false);
These divs, or "textboxes" are contained within a bigger div called content, and this is the click code I have in content:
$content.click(function(e){
//some irrelevant code
if( /* condition to decide if a textbox is clicked */)
{ $(".textbox").each(function(){ //deactivate all except this
if($(this).attr('id') != $eparent.attr('id'))
$(this).deactivateTextBox();
});
// now activate this particular textbox
$eparent.activateTextBox();
}
});
This is pretty much the relevant code related to text boxes. Why is it that whenever I drag something around and then check Visual Event, there are more clicks and dragstops and mouseovers than before? Also, the more user interacts with the page, the longer the events take to complete. For example, I mouseout from a div, but the move cursor takes a loooong time to get back to default. I quit dragging, but everything gets stuck for a while before getting ready to take more user clicks, etc. So I'm guessing the problem has to be that I'm binding too many things to the same events need to be unbinding at some point? It gets so bad that draggable eventually stops working at some point. The textboxes just get stuck - they're still able to be resized, but dragging stops working.
Am I binding events over and over
Yes. Have a look at your code:
$this.mouseenter(function(){
…
$this.mouseleave(function(){
…
$this.click(function(e){
…
});
});
});
That means every time you mouseover the element, you add another leave handler. And when you leave the element, every of those handlers adds another click event.
I'm not sure what you want to do, but there are several options:
bind the event handlers only once, and keep track of the current state with boolean variables etc.
before binding, remove all other event handlers that are already bound. jQuery's event namespacing can help you to remove only those which your own plugin added.
use the one() method that automatically unbinds a listener after firing it.
I'm trying to trigger my own custom events as global events, so that anything on my page can listen to them and react, however, for dynamically added content it's not working. See my fiddle at: http://jsfiddle.net/6TMkG/8/
As far as I understand, the event is triggered for any element in the page that jQuery knows has a handler for it, and it seems it doesn't trigger the event for the li's even though they do have a handler.
Anyone know how to get around this behaviour?
try this
$("#b2").click(function() {
//$.event.trigger("randomEvent");
$('li').trigger('randomEvent');
});
If you want global event, then you could bind the event handler on document, and trigger it on any element in the document.
$(document).on('randomEvent', callback);
$('ul').click(function() {
$(this).trigger("randomEvent");
});
Sorry I completely missed that.. I did not see the first part of your question.. Custom events.. Looks like you are associating the randomEvent but you are not triggering that event when that is associated with it..
Make sure you add the trigger Event in the Document.Ready function so that the evnet handler is associated with as and when the element is available.
I've done this :
http://jsfiddle.net/CS273/4/
On this fiddle, when the mouse reaches the right area of the text input, it changes the cursor (pointer) and creates a click event listener.
When the mouse gets out of the right area, this same event listener is destroyed.
I would call that "on the fly" event listener binding, perhaps it already has a name.
Is it a good thing to do that or not ?
All things being equal, you'll probably never notice a performance hit, but this is a somewhat odd way to do what you want.
I'd suggest re-working your HTML so that the 'x' isn't part of the input and you can just attach a normal event handler.
example: http://jsfiddle.net/cwolves/CS273/6/
See this update to your fiddle: http://jsfiddle.net/maniator/CS273/5/
I made a floating div that handles the click for you.
Here it is with some color so you see it: http://jsfiddle.net/maniator/CS273/7/
The only js you need:
$(".hover").click( function(e) {
$('.filterNameInput').val('').blur();
});
You can add cursor: pointer; to the css of .hover to have it look the same as your current version.