JavaScript (jquery) - Scope issue in click event - javascript

I know this subject has been already discussed in similar topics, but none of the solutions I could find can help me understand the issue I have.
Here is my simplified class and its the usual was I define them.
BottomNav = function() {
this.init();
}
$.extend(BottomNav.prototype, {
init: function(){
this.insue = false;
$(".up").click($.proxy(function () {
var thisinuse = this.inuse;
if(this.inuse===false) {
this.inuse = true;
this.moveSlider('up');
}
},this));
},
moveSlider: function(d){
//some instructions
alert('move slider');
}
});
$(document).ready(function() {
new BottomNav();
});
In FireBug on the breakpoint inside the click event this.inuse is undefined! (this is my problem), my scope looks good on the watch (right panel of firebug), this.insue is false as it should be - sorry I cannot post images yet!
I would be grateful of someone might help identifying this very strange behavior.
I tried some staff like putting the click event definition inside another function but it does not work either. I tried different ways of bindings and it does not work too.
However the below example is working on a number of other classes I made. I could access class scope from events, effects.

It's just a typo:
this.insue = false;
Change insue to inuse and the property will be there :-)
Apart from that, the variable thisinuse is quite superfluous in here. And change the condition to if(! this.inuse) instead of comparing to booleans…

this.inuse can be assigned to a variable out side your click event handler and use the variable inside the handler.

Related

Missing name after . operator

I'm having problem figuring out, what exactly is going wrong here,
The thing that I understand is this keyword is causing the problem but I can't figure out how and why.
I have tried $(this) and (this)
function makeChoice(){
$(".choices").click(".js-choice", function(){
var choice = this.(".js-choice").val();
});
console.log(choice);
}
I'm creating a quiz app that has 4 options for each question, and for each answer there is a class js-choice and I want the answer from only the button that is clicked currently.
It looks like you've potentially made a syntatical error with trying to create a delegate event handler. If so this can be solved by fixing the binding. And moving the log into the event handler.
function makeChoice(){
$(".choices").on("click", ".js-choice", function(){
var choice = $(this).val();
console.log(choice);
});
}

addEventListener("touchstart") doesn’t work on phones [duplicate]

I don't know what I am doing wrong but here is an example of what I am doing and it doesn't seem to work.
someDom.addEventListener('mousemove',function(ev) {self.onInputMove(ev)},false);
someDom.removeEventListener('mousemove',self.onInputMove);
The removeEventListener code is executed but it just doesn't remove the 'mousemove' listener
removeEventListener removes the listener that exactly matches the function that was added.
In this case, the function that addEventListener added was:
var some_func = function(ev) {
self.onInputMove(ev);
};
Store a reference to the actual function and you'll be good. So for example, the following should work:
someDom.addEventListener('mousemove',self.onInputMove,false);
someDom.removeEventListener('mousemove',self.onInputMove,false);
onInputMove is not an event-callback method. So you need to do something like:
var event = function(ev) {self.onInputMove(ev)};
someDom.addEventListener('mousemove', event,false);
someDom.removeEventListener('mousemove', event, false);
Why make it yourself so hard, just use the following to bind an event to an element:
element.onmousemove = function(e) {
// Some code here...
alert("Mouse moved!");
};
Now, when you want to remove the event, just do this:
element.onmousemove = null;
Done!
Hope this helps you guys out!
This page comes first on searching this/such issue on Google. So apart from answers already mentioned, here is one more interesting fact for future:
Leaving out the third optional variable in addEventListener() for useCapture/useBubble (as it defaults to false) does create some issue while removing the same eventlistener with same callback name. I faced this issue while working on chrome. Cant say about other browsers.
So do mention the third variable explicitly as "false".

Creating a custom "event" for a constructor

I am trying to create a custom "event" and I place this inside quotes because it won't be like a regular event per se from the events constructors.
So what I'd like to do is this
animate.addEventListener('animationReadyState',function(e){
if(e.readyState == "complete")
{
console.log("Done");
}
});
var animation = animate(document.getElementById('element'),{
left:"+200px",
top:"+200px",
easing: {
effect: "easeInOutBounce",
elasticity:1.5
}
});
My problem is how to fire off the "event"? I have the readyState changing throughout my code my problem is firing off this "event".
As of right now with using the events contructors I only get one readyState change fired off which is the complete. But I have others
initialising
invoked
animating
complete
No others are firing off.
Example of my Events Constructors:
var animateStateChange = new CustomEvent('animateStateChange',{ 'state' : null });
function initAnimate(){
animateStateChange.state = "initialising";
document.dispatchEvent(animateStateChange);
}
The problem with this is I'd have to do document.addEventListener or the element.addEventListener though putting the event listener on the element that is animating seems logical I'm not sure how to make it only fire from the element and not say on document... Maybe a little crash course on Custom Events or maybe a "hack" event firing system, even examples I can see logically.
This may give a better example of what I am looking for if you to this fiddle
I am not sure if my solution will answer your query, but i tried to use custom events considering situation given above. Also, I see that there is some glitch in dispatchEvent returned value if any handler is provided. Separately i try to return false from handler, but that too din't worked. Below might help you to understand javascript custom event a bit :
Check this link for working code:
http://jsfiddle.net/3q0vubyp/1/
var animation = animate(document.getElementById('element'),{
left:"+200px",
top:"+200px",
easing: {
effect: "easeInOutBounce",
elasticity:1.5
}
});
function handler(e){
if(e.detail.state === "complete"){
alert('Complete State');
return false;
//e.preventDefault();
//e.stopPropagation();
}
}
function animate(element, anim){
var i=0;
var j=true;
var state=['initialize','invoked','animating','complete'];
element.addEventListener('animateStateChange',handler);
while(j){
var animateStateChange = new CustomEvent('animateStateChange',{ 'detail' : {"state": state[i++]} });
//if(!element.dispatchEvent(animateStateChange)){
// j=false;
//}
element.dispatchEvent(animateStateChange);
if(i==4)
j=false;
};
}
In docs of dispatchEvent,doclink It is clearly mentioned that the return value is false if at least one of the event handlers which handled this event called Event.preventDefault(). Otherwise it returns true. That din't worked for me.
Hope that helps!

Can't listen to global event in jQuery

Another question on stackoverflow pointed out that it should be possible to trigger an event on all listning objects using:
$.event.trigger('customEvent');
However this does not seem to work for me in an example like:
$('body').bind('customEvent', function(){ alert('Working!'); });
Am I doing something completely wrong, or has this great functionality been disabled?
It looks like that functionality has been removed. Browsing through the tags I managed to find this TODO in v1.8b1:
// TODO: Stop taunting the data cache; remove global events and always attach to document
And it was removed as of v1.9.0.
There is nothing stopping you from implementing it based on the old source code here (v1.6.2), but it looks like it was doing naughty things talking to jQuery.cache so it's probably best to live without it or come up with another solution.
$('*').trigger('customEvent');
Perhaps? (jsFiddle)
Or a more efficient approach of keeping track of each subscription and calling .trigger() on that.
jsFiddle
var customSubs;
$.fn.subscribeCustom = function (fn) {
this.on('customEvent', fn);
if (!customSubs)
customSubs = this;
else
customSubs = customSubs.add(this);
};
$('span').subscribeCustom(function () {
alert('span!');
});
$('div').subscribeCustom(function () {
alert('div!');
});
customSubs.trigger('customEvent');

Selector to apply jQuery event to two DOM ids

I have two select menus (#id1 and #id2) that, when validated as containing a user error, should instigate some DOM changes (remove error notice) when either one of them gets interacted with.
Again:
var Heat_Check = jQuery('#id1' or '#id2').change(function() { ... });
PS. I know there's no return value from that chain.
May be you wanted to check if change is triggered from either of those select. Try below,
var Heat_Check = false;
jQuery('#id1, #id2').change(function() { Heat_Check = true; });
function heatCheck () {
if(Heat_Check) {
//Do your stuff
console.log('It is hot');
}
}
The comment from #Vega is right, but for completeness you can also do this:
heatChangeHandler = function() {
// ....
};
$('#id1').change(heatChangeHandler);
$('#id2').change(heatChangeHandler);
In general it is better to put multiple selectors in one $(), but it's worth knowing that functions can be addressed as variables, and thus referenced many times.

Categories