I can't access array/obj outside jQuery event function - javascript

So I've got an object, or array, declared at the beginning of anything, outside everything:
var Thing = {title:'horse'};
Then I've got:-
$('.clickedIt').fadeOut(200, function() { console.log(Thing.title); }
That will fail. However, if I place above that same console log out of fadeOut, it'll be fine.

If you want something to be global, just define it on the window Object.
window.Thing = { title: 'horse '};
Then use it like so:
$( '.clickedIt' ).fadeOut(200, function() {
console.log( window.Thing.title );
});
Just a note, putting a number of variables on the window Object is not recommended, I would recommend looking into name-spacing: http://addyosmani.com/blog/essential-js-namespacing/
Here is an example:
//simple JavaScript module
( function( window ) {
//define your applications root namespace
window.myApp = {
Thing: { title: 'horse '}
};
})( window );
//jQuery ready function
$( function() {
$( '.clickedIt' ).fadeOut( 200, function() {
console.log( myApp.Thing.title );
});
});

The value you assigned to title horse is undefined wrap it within quotes to make it string litral,
Live Demo
var Thing = {title:'horse'};
$('.clickedIt').fadeOut(200, function() { console.log(Thing.title); })​

Related

Passing a variable from one function to another in JQuery?

I have 2 functions and i was wondering if it is possible to use a variable that is defined in 1 function, in another function. Basically I have the following code:
(function( $ ) {
//On input
$("#anid").on("input", function() {
var variable = 'testing';
});
//On change
$('#dropdown').change(function(){
var variable2 = variable;
});
})( jQuery );
Any help is greatly appreciated!
Just declare the var variable out of that context.
var variable = 'initialValue';
(function( $ ) {
//On input
$("#anid").on("input", function() {
variable = 'new Value'
});
//On change
$('#dropdown').change(function(){
//don't even need another one here..
//variable is accessible from here
});
})( jQuery );
I'll delete this once you comment and say to do so as the answer above is fine. If you do not need variable elsewhere, then it will be cleaner to do:
(function( $ ) {
var variable = 'initialValue';
//On input
$("#anid").on("input", function() {
variable = 'new Value'
});
//On change
$('#dropdown').change(function(){
//don't even need another one here..
//variable is accessible from here
});
})( jQuery );

JavaScript ignores bool

i try to do something like a status-check to enable/ disable settings.
// file 1
function settings( valStatus ){
var status = valStatus;
this.getStatus = function(){
return status;
}
this.setStatus = function( valStatus ){
status = valStatus;
}
}
calling this function here:
// file 2
$settings = new settings( false );
$(document).ready(function() {
$( '#openSettings' ).on('click', function() {
$settings.setStatus( true );
enableSettings();
});
$('#save').on('click', function(){
$settings.setStatus( false );
closeSettings();
});
});
// file 1
enableSettings = function() {
if( $settings.getStatus() === true ){
//toggle emptyLink
$('.myButton').on('click', function(){
alert($settings.getStatus());
});
}
}
So as startup while clicking on "myButton" nothing happens.
After Clicking on "openSettings" and then on "myButton" i get the alert "true";
After clicking on "save" and then on "myButton" again, i get the alert "false", but it does not even trigger, because i checked it befere.... can somebody help me please?
Where is my mistake?
I think you probably want to put the check for status inside the .myButton click handler instead of outside. That way you only need to apply the handler once and it will either work or not depending on the value of status.
$(document).ready(function() {
var $settings = new settings( false ); // keep out of global scope
$( '#openSettings' ).on('click', function() {
$settings.setStatus( true );
});
$('#save').on('click', function(){
$settings.setStatus( false );
});
$('.myButton').on('click', function(){
if ($settings.getStatus()) {
alert($settings.getStatus());
}
});
});
First of all, you can write JavaScript with less code than e.g. Java. You don't need the getter and setter methods since there is no package visibility. Since you do nothing with the setters you can access your fields directly. This is less code to read and less code where you can have errors. So get rid of useless code (remember this is not the request do code one-liners). Search the internet for "clean code".
Since you are in JavaScript you can do better than that. A smaller approach to store your information.
var mySetting = {};
mySetting.status = true
console.log( mySetting.status );
mySetting.status = false;
console.log( mySetting.status );
Remember to keep your global space clean! Search the internet for "javascript global scope pollution". So do this within your scope.
Your main problem is, that you are using closures. You probably don't want to use it in your case. Search the internet for "javascript closure tutorial". There are a lot of good ones out there.
Since you are using the Jquery, you can use the .data() function to store your information.
See http://api.jquery.com/jquery.data/
$(function(){
$( '#openSettings' ).on('click', function() {
$('#settings').data( "status", true );
enableSettings();
});
$('#save').on('click', function(){
$('#settings').data( "status", false );
closeSettings();
});
$('.myButton').on('click', function(){
alert($('#settings').data());
});
});
Or within the HTML itself. See http://api.jquery.com/attr/
$('#settings').attr( "status", true );
console.log( $('#settings').attr( "status" ) );
Or as switches.
$('#settings').addClass( "settingsEnabled" );
$('#settings').removeClass( "settingsEnabled" );
console.log($('#settings').hasClass('settingsEnabled'));
Use .data() if you want to store object references and HTML for simple information like switches etc. The benefit is, that you can reach that information even with CSS.
And please get rid of the $ prefix in your own code since it has no meaning. If you use frameworks like angular it will help you to identify the origin or like the $$ the ("don't") use of it.

Store jQuery to a variable

I'm using Leaflet to make a map with a layer selector, and jQuery to bind to the radios made by the Leaflet layer selector. I'm able to view which radio was selected in an alert using the following code
$("[name='leaflet-base-layers']").change( function () {
alert('Layers selected: ' + $(this).parent().text());
});
I'd like to know how to store that data as a Javascript variable to be compared to in
if (ExampleVariable == "Phoenix") {
map.panTo([33.4314,-112.0747]);
}
Is there any way to do this, and if not, how can I use jQuery's internal data storage to do this?
Did you mean something like this?
var lastSelected = null; // if you need it later for anything
$("[name='leaflet-base-layers']").change(function(){
var text = $(this).parent().text();
lastSelected = text;
// use the text for anything
switch(text) {
case "Phoenix":
map.panTo([33.4314,-112.0747]);
break;
case "SomethingOther":
map.panTo([10, 120]);
break;
}
});
$("[name='leaflet-base-layers']").change( function () {
alert('Layers selected: ' + $(this).parent().text());
ExampleVariable = $(this).parent().text();
});
You could either save the value to a variable declared globally
var selLayer; // global
$( "[name='leaflet-base-layers']" ).change(function () {
selLayer = $( this ).parent().text();
});
Or, using jQuery data stores as
$( "[name='leaflet-base-layers']" ).change(function () {
$( this ).data( "selLayer", $( this ).parent().text());
});
if ($( "[name='leaflet-base-layers']" ).data( "selLayer" ) === "Phoenix") {
map.panTo( [33.4314,-112.0747] );
}
You should ideally store leaflet layer element to avoid jQuery lookup again and again.
var $leafletBase = $( "[name='leaflet-base-layers']" );
The simplest way is like this:
$("[name='leaflet-base-layers']").change(function() {
leafletText = $(this).parent().text());
});
Note that if you use the var keyword in that assignment, you're going to have scoping problems with your later comparison since that variable won't be accessible outside of that particular function. By omitting the var keyword, you're putting the var in the global context, which is something you should generally avoid when possible.
I would highly suggest learning about variable scoping as it's an important concept to grasp.

JS Jquery Namespace Calling Functions

Ok terrible title but I couldn't think of another description.
I have the following code:
jQuery( document ).ready( function( $ )
{
$.myNamespace = {
init: function()
{
$('.button').click(function() {
this.anotherFunction();
});
},
anotherFunction: function()
{
alert('insidefunction');
}
}
$.myNamespace.init();
});
As you can see I am trying to call anotherFunction from inside init and have there the two ways I tried but didn't work. So how am I able to call that function or is my concept wrong?
jQuery( document ).ready( function( $ )
{
$.myNamespace = {
init: function()
{
var a=this;
$('.button').click(function() {
a.anotherFunction();
});
},
anotherFunction: function()
{
alert('insidefunction');
}
}
$.myNamespace.init();
});
http://jsfiddle.net/ZpAtm/2/
Absolutely calling it within the click handler changes things, as this inside any jQuery event handler is set to the element that caused the event.
Instead, try using the following pattern:
jQuery(document).ready(function($) {
$.myNamespace = (function() {
function init() {
$('.button').click(function() {
anotherFunction();
});
}
function anotherFunction() {
alert('insidefunction');
}
// return an object with all the functions you want
// available publically as properties. Don't include
// any "private" functions.
return {
init: init,
anotherFunction: anotherFunction
};
})();
$.myNamespace.init();
});​

Why a separately defined function does not work on a "domready" event in JavaScript?

I am quite new to JavaScript. I am trying to set equal heights to some elements. I managed to do everything except moving the function outside the "addEvent" declaration.
In other words, this code works:
window.addEvent('domready', function() {
var elements = $$( 'div#leftcolumn div.module_menu' );
if( elements && elements.length > 1 ) {
var heights = [];
elements.each( function( el ) {
heights.push( el.getStyle('height').toInt() );
});
maxHeight = Math.max.apply( Math, heights ) + "px";
elements.each( function( el ) {
el.setStyle('height', maxHeight );
});
delete(heights);
}
}
);
while this code does NOT work:
function matchHeight( selector ) {
var elements = $$( selector );
if( elements && elements.length > 1 ) {
var heights = [];
elements.each( function( el ) {
heights.push( el.getStyle('height').toInt() );
});
maxHeight = Math.max.apply( Math, heights ) + "px";
elements.each( function( el ) {
el.setStyle('height', maxHeight );
});
delete(heights);
}
}
window.addEvent( 'domready', matchHeight( 'div#leftcolumn div.module_menu' ) );
I already test with simpler functions and it works, like e.g:
window.addEvent('domready', function() { alert('test'); } )
is equivalent to
function giveMessage() { alert('test'); }
window.addEvent( 'domready', giveMessage())
why is that?
It's because you need to remove the parenthesis; a function is an object, and you need to pass the function, not its return value. So, for your first example, you should have:
window.addEvent('domready', function() { matchHeight('div#leftcolumn div.module_menu'); } );
Instead. For your second example, it's:
function giveMessage() { alert('test'); }
window.addEvent( 'domready', giveMessage)
Again, you pass the object giveMessage, not the result obtained after invoking it.
You forgot to put your matchHeight call in a closure. Change your last line to:
window.addEvent( 'domready', function(){matchHeight( 'div#leftcolumn div.module_menu' )} );
K so that link is looking for a pointer to the function. When you pass it an anonymous function (as in eg #1) that function is created/stored in memory, and that location is passed in. Your second case though, JS executes the function (because of your brackets+arguments) and then passes the result as the pointer... which isn't want you want.
What you'd need to do instead is:
function setup() {
matchHeight( 'div#leftcolumn div.module_menu');
}
window.addEvent('domready',setup);
Or still use an anonymous function:
window.addEvent('domready',
function() {matchHeight( 'div#leftcolumn div.module_menu');});
FWIW window.addEvent isn't totally cross-browser compatible, see also window.attachEvent

Categories