jQuery pass $this to function parameter - javascript

I have:
<img id="leftBubble" class="bubbles" src="left.png" />
<img id="rightBubble" class="bubbles" src="right.png" />
And a hover event like so:
$(".bubbles").each(function(){
$(this).hover(function() {
pause($(this));
}, function() {
play(4000, $(this));
});
});
My pause() function does not seem to be working
function pause(pauseMe) {
if (pauseMe == $("#leftBubble")) {
clearTimeout(timer1); //this is never reached
} else if (pauseMe == $("#rightBubble")) {
clearTimeout(timer2); //nor this
}
}
Any idea to make the hover event pass $this as the parameter for the pause function?

Each time you call $, it returns a different result set object, even if the result contents are the same. The check you have to do is:
if (pauseMe.is("#leftBubble")) {

Try like below,
function pause(pauseMe) {
if (pauseMe == "leftBubble") {
clearTimeout(timer1);
} else if (pauseMe == "rightBubble") {
clearTimeout(timer2);
}
}
and in the caller,
$(".bubbles").each(function(){
$(this).hover(function() {
pause(this.id);
}, function() {
play(4000, $(this));
});
});

In javascript, this is redefined each time you enter a new function definition. If you want to access the outside this, you need to keep a reference to it in a variable (I used the self) variable.
$(".bubbles").each(function(){
var self = this;
$(this).hover(function() {
pause($(self));
}, function() {
play(4000, $(self));
});
});
I don't know if your comparison between jQuery objects will work though. Maybe you can compare the DOM elements: pauseMe[0] == $("#leftBubble")[0], or, as mentioned, the ids.

When you call $( ... ) it generates new object that not the same that was genereted when you call $( ... ) last time, with same parametrs.
Anyway, you can't compare objects with == in javascript. It returns true only if it liks on same object.
a = {b:1}
c = {b:1}
d = c
a == b // false
d == c // true

Related

jQuery, on input[type=radio] change verify something if false, call 2 other functions

I am trying to create an event that fires some functions depending on the id of an input[type=radio]. If the Id clicked is different to maybe_evtDiag, it should call this.applySubConditionalRequired(); and this.bindUISubActions();. Why is my code not working?
var SubFormStuff = {
init: function()
this.applySubConditionalRequired();
this.bindUISubActions();
},
bindUISubActions: function() {
// when a radio or checkbox changes value, click or otherwise
$("input[type='radio'].stepThreeDiag").change(function() {
if($(this).attr("id") == "maybe_evtDiag") {
$(this).prop('checked', false);
}else{
//this is not working //
applySubConditionalRequired(this);
displaySubFormRequired(this);
}
});
},
applySubConditionalRequired: function() {
$(".require-if-subevent-active").each(function() {
var el = $(this);
// does something
});
},
displaySubFormRequired: function() {
$(".div-subevent-class").each(function() {
var el = $(this);
// does something else
});
}
};
SubFormStuff.init();
Like you did in the init(), add a reference to the object (this) to call a sibling function (not to lose the context):
bindUISubActions: function() {
var _SubFormStuff = this;
// when a radio or checkbox changes value, click or otherwise
$("input[type='radio'].stepThreeDiag").change(function() {
if($(this).attr("id") == "maybe_evtDiag") {
$(this).prop('checked', false);
} else{
_SubFormStuff.applySubConditionalRequired();
_SubFormStuff.displaySubFormRequired();
}
});
More details on scope and context in JavaScript
You should call the methods like this:
bindUISubActions: function() {
// Store the reference to the current object
var self = this;
// when a radio or checkbox changes value, click or otherwise
$("input[type='radio'].stepThreeDiag").change(function() {
if($(this).attr("id") == "maybe_evtDiag") {
$(this).prop('checked', false);
} else{
self.applySubConditionalRequired();
self.displaySubFormRequired();
}
});
}
This way you can assing to self the current scope, and use it later on any other function call in the same execution scope.
More about javascript scope
You are trying to call applySubConditionalRequired(this) and displaySubFormRequired(this) in the wrong context you should get applySubConditionalRequired and displaySubFormRequired are not defined.
Try this:
bindUISubActions: function() {
// when a radio or checkbox changes value, click or otherwise
var that = this;
$("input[type='radio'].stepThreeDiag").change(function() {
if($(this).attr("id") == "maybe_evtDiag") {
$(this).prop('checked', false);
}else{
//it should work now //
that.applySubConditionalRequired(this);
that.displaySubFormRequired(this);
}
});
},

Passing parameters to a event listener function in javascript

Hello I have some code in which I take user input through in html and assign it to,two global variables
var spursscoref = document.getElementById("spursscore").value;
var livscoref = document.getElementById("livscore").value;
Which next show up in this addeventlistener function as parameters of the whowon function
var d = document.querySelector("#gut2");
d.addEventListener("click", function () {
whowon(spursscoref, livscoref, spurs, liverpool)
}, false);
The click event is meant to trigger the whowon function and pass in the parameters
function whowon(FirstScore, SecondScore, FirstTeam, SecondTeam) {
if (FirstScore > SecondScore) {
FirstTeam.win();
SecondTeam.lose();
} else if (FirstScore < SecondScore) {
SecondTeam.win();
} else {
FirstTeam.draw();
SecondTeam.draw();
}
}
However the values are null,as I get a cannot read properties of null error on this line
var spursscoref = document.getElementById("spursscore").value;
I am pretty sure the problem is coming from the addlistener function,any help would be appreciated
Well you could do something like this -
$( document ).ready(function() {
var d = document.querySelector("#gut2");
d.addEventListener("click", function () {
var spursscoref = document.getElementById("spursscore").value;
var livscoref = document.getElementById("livscore").value;
whowon(spursscoref, livscoref, spurs, liverpool)
}, false);
});
Wrap your code in $(document).ready(function(){}). This will ensure that all of your DOM elements are loaded prior to executing your Javascript code.
Try putting all of your code inside this
document.addEventListener("DOMContentLoaded", function(event) {
//Your code here
});
My guess is that your code is executed before the html actually finished loading, causing it to return null.

Define a javascript variable under conditions with jquery

Like the title says, I would like to fill a variable up under some conditions
I thought I could do like that but no :
var content = $(function() {
if ($('#content').length) {
return $('#content');
}
if ($('#content_no_decoration').length) {
return $('#contenu_no_decoration');
}
if ($('#full_content').length) {
return $('#full_content');
}
if ($('#full_content_no_decoration').length) {
return $('#full_content_no_decoration');
}
});
So I thought that the javascript variable 'content' would be one of the jquery object representing an element in the dom. But it seems that 'content' is the function.
I guess you imagine what i want to do.. What is the syntax with JQuery ?
Thank you
$(function() { }) is short-code for the DOMReady event. You need to explicitly define a function, and then assign the return value to your variable.
For example:
function getObj()
{
if($('#content').length)
{
return $('#content');
}
if($('#content_no_decoration').length)
{
return $('#contenu_no_decoration');
}
if($('#full_content').length)
{
return $('#full_content');
}
if($('#full_content_no_decoration').length)
{
return $('#full_content_no_decoration');
}
}
You can then assign the value as :
var content = getObj();
You will need to call the assignment when the DOM is ready though, otherwise the selectors will not trigger as expected. For example:
$(function() {
var content = getObj();
});
You are only declaring the function, so content contains a pointer to the function.
Execute it and you are fine:
var content = function() {
if ($('#content').length) {
return $('#content');
}
if ($('#content_no_decoration').length) {
return $('#contenu_no_decoration');
}
if ($('#full_content').length) {
return $('#full_content');
}
if ($('#full_content_no_decoration').length) {
return $('#full_content_no_decoration');
}
}();
But you don't really need a function here. If the script tag is at the bottom of the page (right before the closing </body>-tag), or the assignment is within a load handler you could use:
var content = $('#content').length
? $('#content')
: $('#content_no_decoration').length
? $('#content_no_decoration')
: $('#full_content').length
? $('#full_content')
: $('#full_content_no_decoration').length
? $('#full_content_no_decoration')
: undefined;
Or use jQuery to your advantage and keep things really short:
var content =
$('#content,#content_no_decoration,#full_content,#full_content_no_decoration')
.get(0);
// if none of the elements exist, content will be undefined, otherwise
// it will contain [a JQuery Object of] the first existing element
why you don't do like that ?
function thatsAGoodName() {
if ($('#content').length) {
return $('#content');
}
if ($('#content_no_decoration').length) {
return $('#contenu_no_decoration');
}
if ($('#full_content').length) {
return $('#full_content');
}
if ($('#full_content_no_decoration').length) {
return $('#full_content_no_decoration');
}
}
var content = thatsAGoodName();
The function
$(function() {
// DOM safe to use do stuff
})
Is shorthand for the document ready event. This tells you the coder that the dom is safe to use.
You would not really return anything from this event.
content is an object because you're setting it to a object here:
var content = $(function() {
What you probably intended was:
var content;
if ($('#content').length) {
content = $('#content');
}
if ($('#content_no_decoration').length) {
content = $('#contenu_no_decoration'); // Is #contenu a typo???
}
if ($('#full_content').length) {
content = $('#full_content');
}
if ($('#full_content_no_decoration').length) {
content = $('#full_content_no_decoration');
}
Note, that this will have a reference to an element now. If you want the actual content you'll need to pull it out with something like html() or val().
You are using the shorthand for the jQuery ready event ($(function() {. What I believe you want is a self invoking function:
// remove the call to jQuery
var content = (function() {
if ($('#content').length) {
return $('#content');
}
// ... more
})(); // invoke the function, which should return a jQuery object
You may need to wrap this in a document.ready, depending on where your script is executed.
Rearrange it a little bit and it should work:
$(function () {
var content = (function() {
var regularContent = $('#content');
if (regularContent.length !== 0) {
return regularContent;
}
var contentNoDecoration = $('#content_no_decoration');
if (contentNoDecoration.length !== 0) {
return contentNoDecoration;
}
var fullContent = $('#full_content');
if (fullContent.length !== 0) {
return fullContent;
}
var fullContentNoDecoration = $('#full_content_no_decoration');
if (fullContentNoDecoration.length !== 0) {
return fullContentNoDecoration;
}
}());
});
This code is basically saying once the DOM is ready (the $(function () { ... }); part), run this anonymous function (the (function () { ... }()); part) and assign its return value to content.
Edit: Also, you're losing efficiency by running each of your selectors twice instead of just once.
It's true that content is the function, but you can use that function. Like:
var result = content();
Edit:
Remove the $() around var content = $({/* code */}) and it works.

jQuery, associative array and binding events

I would like to bind the same event to 3 checkboxes but with a different target each time:
var checkboxes = {
'selector1' : 'target1',
'selector2' : 'target2',
'selector3' : 'target3',
};
for (selector in checkboxes) {
var target = checkboxes[selector];
if (jQuery(selector).is(':checked')) {
jQuery(target).show();
}
else {
jQuery(target).hide();
}
jQuery(selector).bind('change', function() {
if ($(this).is(':checked')) {
jQuery(target).show();
}
else {
jQuery(target).hide();
}
});
};
But it doesn't work: on "change", the 3 selectors show/hide the 3rd target.
That's because the code in the event handler will use the variable target, not the value of the variable as it was when the event handler was created. When the event hander runs, the variable will contain the last value used in the loop.
Use an anonymous function to create a closure, that captures the value of the variable:
for (selector in checkboxes) {
var target = checkboxes[selector];
if (jQuery(selector).is(':checked')) {
jQuery(target).show();
} else {
jQuery(target).hide();
}
(function(target){
jQuery(selector).bind('change', function() {
if ($(this).is(':checked')) {
jQuery(target).show();
} else {
jQuery(target).hide();
}
});
})(target);
};
Side note: You can use the toggle method to make the code simpler:
for (selector in checkboxes) {
var target = checkboxes[selector];
jQuery(target).toggle(jQuery(selector).is(':checked'));
(function(target){
jQuery(selector).bind('change', function() {
jQuery(target).toggle($(this).is(':checked'));
});
})(target);
};
It doesn't work because target isn't scoped inside of a function. Blocks DO NOT provide scope in javascript.
But I've reduced it down for you and hopefully this will work out:
$.each(checkboxes, function(selector, target) {
$(selector).change(function () {
$(target).toggle($(selector).is(':checked'));
}).trigger('change');
});
target scope is the problem !
You could have simpler code:
use data for the handler
use .toggle(condition)
$.each(checkboxes, function(selector, target) {
$(selector).on('change', {target:target}, function (evt) {
$(evt.data.target).toggle($(this).is(':checked'));
}).change();
});

How do I make a function to run only when the mouse is NOT hovering a specified div?

what I got now is:
function()
{
setInterval("getSearch()",10000);
getSearch();
}
);
But I want this interval to pause if the mouse cursor is placed inside a div on my website. How do I attack this problem? Surely I need to give the div an ID.. But some input on how to make the javascript/jquery part is much appreciated.
EDIT: More of my code.. I'm not quite sure where to insert the code in the answers inside this:
$(
function()
{
setInterval("getSearch()",10000);
getSearch();
}
);
TwitterCache = {};
function getSearch()
{
var url = "http://search.twitter.com/search.json?q=test&refresh=6000&callback=?"; // Change your query here
$.getJSON
(
url,
function(data)
{
if( data.results ) // Checks to see if you have any new tweets
{
var i = -1, result, HTML='', HTML2='';
while( (result = data.results[++i]) && !TwitterCache[result.id] )
{
insert html.. blabla}
setInterval returns a "reference" to that interval you set up, allowing you to stop it with window.clearInterval(), and that's what you have to do:
var myInterval;
function startMyInterval() {
if (!myInterval) {
// It's better to call setInterval width a function reference, than a string,
// also always use "window", in case you are not in its scope.
myInterval = window.setInterval(getSearch, 10000);
}
}
function stopMyInterval() {
if (myInterval) {
window.clearInterval(myInterval);
}
}
startMyInterval(); // Start the interval
jQuery("#myDiv").hover(stopMyInterval, startMyInterval);
Set a global variable
var intID;
Assign setInterval to this variable
intID = setInterval("getSearch()",10000);
Set an id for the div
$("#divid").hover(function(){
clearInterval(intID);
},
function(){
// set the interval again
});
I think this should work:
$("#divID").hover(
function () {
PauseTheInterValThing()
},
function()
{
setInterval("getSearch()",10000);
getSearch();
}
);
The simplest way, and the shortest
Simplest method would be:
<div id="yourDiv">
EXAMPLE TEXT
</div>
<script language="Javascript">
var interval = setInterval("getSearch()",1000);
document.getElementById("yourDiv").addEventListener('mouseover', function()
{
clearInterval(interval);
},false);
document.getElementById("yourDiv").addEventListener('mouseout', function()
{
interval = setInterval("getSearch()",1000);
},false);
</script>
insert this in your dom-ready function:
var inv = setInterval("getSearch",1000);
$('#yourdiv').mouseover(function(){
clearInterval(inv);
}).mouseout(function(){
inv = setInterval("getSearch",1000);
})

Categories

Resources