pass variable from hover to offhover - javascript

http://jsfiddle.net/MwQbE/
i have the jQuery Below but i cant get the variables to pass to the second function
$("img").hover(function(){
var $image = $(this);
var $imageNowWidth = $image.width();
},function() {
// get variable value for $image and $imageNowWidth
});​
When testing on jsFiddle it doesn't work, what can I do to pass the variable to the second function?

Simply define those 2 variables outside .hover and then you can use them inside mouseleave function. See below,
var $image, $imageNowWidth;
$("img").hover(function(){ //mouseenter
$image = $(this);
$imageNowWidth = $image.width();
},function() { //mouseleave
//$image and $imageNowWidth is accessible HERE
});​
Just want to clarify that this will be available inside mouseleave function so you can do the same or more w.e you are doing inside mouseenter

Define getter and setter for image and imageNoWidth as below,
var getImage, getImageNoWidth;
$("img").hover(function(){
$image = $(this);
$imageNowWidth = $image.width();
getImage = function(){
return $image;
};
getImageNoWidth = function(){
return $imageNowWidth;
};
},function() {
// get variable value for $image (getImage()) and $imageNowWidth (getImageNoWidth())
}

Declare the variable outside, so it is accessible in both functions.
var image;
var imageNowWidth;
$("img").hover(function(){
image = $(this);
imageNowWidth = $image.width();
},function() {
// get variable value for $image and $imageNowWidth
});​

Store the variable directly on the jquery object using the jquery 'data' method :
$("img").hover(function(){
var $image = $(this);
$image.data('imageNowWidth',$image.width());
},function() {
var previousImageWidth = $(this).data('imageNowWidth');
// do whatever you want to do with the width
});​

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 );

Update element text when clicked

$("#readMain").delegate("span", "click", function() {
var toSend = $(this).text();
$(this).text(function() {return "test1";});
$.post('/render/', {'word': toSend}, function(data){
$(this).text(data);
alert(data); //for testing
});
});
I'm trying to have the word clicked updated. It works fine the first time (it changes to 'test1'), but after the post call, it doesn't work anymore?
What am I doing wrong
this doesn't refers to span element in $.post() callback method, store the reference of $(this) in a variable and use it wherever required.
//Store the reference
var _this = $(this);
$.post('/render/', {'word': toSend}, function(data){
//Use it later
_this.text(data);
alert(data); //for testing
});
Additionally, delegate() is deprecated use .on()
$("#readMain").on("click", "span", function() {
//Store the reference
var _this = $(this);
var toSend = _this.text();
_this.text("test1");
$.post('/render/', {'word': toSend}, function(data){
_this.text(data);
alert(data); //for testing
});
});
This in that context refers the first time to the "span", the second time it refers to the window object.
Besides that, delegate is old jQuery, you can use '.on' now.
You'll nee to update the function like this:
$("#readMain").on("click", "span", function() {
var span = $(this);
var toSend = span.text();
$.post('/render/', {'word': toSend}, function(data){
span.text(data);
alert(data); //for testing
});
});
this is only valid in the current scope which means every function, class, closure, ..., has it's on this. Save a reference to your first this in a var to access it later.
$("#readMain").delegate("span", "click", function() {
var span = $(this);
var toSend = span.text();
span.text(function() {return "test1";});
$.post('/render/', {'word': toSend}, function(data){
span.text(data);
alert(data); //for testing
});
});
The context in $.post callback will be changed. You can declare a variable and set the context. See the code below.
$("#readMain").on("span", "click", function() {
var self = $(this),
toSend = self.text();
self.text(function() {return "test1";});
$.post('/render/', {'word': toSend}, function(data){
self.text(data);
alert(data); //for testing
});
});

Optimizing JQuery

I have Jquery code that looks like this. Is there a way to optimize this code? What happens if the image doesn't have a title attribute? Should I insert a case for using the value of the alt attribute as a backup and If I'm chaining the .attr() function multiple times, then it'd be cleaner code I you just ran the .attr() function a single time passing a value pair object of all my properties to the function. How can I do this ?
$(function() {
$('.component-individual-detail-profile').each(function() {
var $self = $(this), $images = $self.find('.photos');
$images.find('li').click(function(e) {
e.preventDefault();
var thumb = $(this);
$images.find('.selected')
.attr('src', thumb.find('img').attr('src'))
.attr('alt', thumb.find('img').attr('alt'))
.attr('title', thumb.find('img').attr('title'));
});
});
});
You can store the attributes in a array, and cache the $thumb.find('img') selector:
$('.component-individual-detail-profile').each(function() {
var $self = $(this);
var $images = $self.find('.photos');
$images.find('li').click(function(e) {
e.preventDefault();
var $thumb = $(this).find('img');
var $selected = $images.find('.selected');
$.each(['src', 'alt', 'title'], function(index, attrName){
$selected.attr(attrName, $thumb.attr(attrName));
});
});
});
Have you considered var thumb = $(this).find("img") for starters? Anywhere your code repeats function calls, you're probably doing something wrong.
Regarding "what if there is no attribute", you can do thumb.attr('title') || thumb.attr('alt'), using the logical or (||) to provide a value if the first one doesn't exist.
According to the documentation, you can do...
$images.find('.selected').attr({
src: thumb.attr('src'),
alt: thumb.attr('alt'),
title: thumb.attr('title') || thumb.attr('alt')
});

$(this) and scope - passing a specific element

I have a variety of .img-drop-zones and upon drop a file is read, I wish to display it on top of the specific drop zone it was placed on, but how do I get it? $(this) does not work because of scope, how can I pass it through?
$('.img-drop-zone').on('drop', function(e){
var files = e.originalEvent.dataTransfer.files;
$.each(files, function(index, file){
p.file.read(file, function(content) {
//how can I get the img-drop zone here?
});
})
});
Just declare an additional variable in the outer scope that you can refer to within the $.each closure:
var $this = $(this);
$.each(..., function() {
// use $this here to refer to the img-drop-zone
});
When referring to an object to something that isn't a jQuery object it's more common to use self or that.
$(this) is what you need
$('.img-drop-zone').on('drop', function(e){
var files = e.originalEvent.dataTransfer.files;
var dropJone = $(this);
$.each(files, function(index, file){
p.file.read(file, function(content) {
//how can I get the img-drop zone here?
//use dropJone here
});
})
});

Call Javascript Function with argument and use argument as a variable name

I've the following snip of a code:
var about = "about.html";
function loadPage(target){
$("#dashboard").load(target);
}
$(".nav li").click(function(){
loadPage($(this).attr("class"));
});
So when I click on a button like <li class="about">, target is = about.
But in that way, $("#dashboard").load(target); doesn't load the variable about which is the html-file which I want to load.
So how is it possible to call the variable in this way?
You seem to miss the .html part. Try with
$("#dashboard").load(target+'.html');
But, supposing you have only one class on your li element, you'd better use this.className rather than $(this).attr("class").
EDIT :
if you want to use your about variable, you may do this :
$("#dashboard").load(window[target]);
But it would thus be cleaner to have a map :
var pages = {
'about': 'about.html',
'home': 'welcome.jsp'
}
function loadPage(target){
$("#dashboard").load(pages[target]);
}
$(".nav li").click(function(){
loadPage(this.className);
});
A stupid answer : create a <a> tag, and set its href attribute to the correct value.
Otherwise :
A standard way to store key: values pairs in javascript is to use a plain object :
var urls = {};
urls['about'] = 'mysuperduperurlforabout.html';
function loadPage(target) {
var url = urls[target];
//maybe check if url is defined ?
$('#dashboard').load(url);
}
$(".nav li").click(function(){
loadPage($(this).attr("class") + ".html");
});
or
$("#dashboard").load(target+".html");
You can call the variables like this (if that's what you asked):
var test = 'we are here';
var x = 'test';
console.log(window[x]);
It's similar to the $$ in PHP. The output will be:
we are here in the console window.
You could put the "about" as an object or array reference similar to:
var pageReferences = [];
pageReferences["about"] = "about.html";
var otherReference = {
"about": "about.html"
};
function loadPage(target) {
alert(pageReferences[target]);
alert(otherReference[target]);
$("#dashboard").load(target);
}
$(".nav li").click(function () {
loadPage($(this).attr("class"));
});
Both of these alerts will alert "about.html" referencing the appropriate objects.
EDIT: IF you wished to populate the object based on markup you could do:
var otherReference = {};
$(document).ready(function () {
$('.nav').find('li').each(function () {
var me = $(this).attr('class');
otherReference[me] = me + ".html";
});
});
You could even store the extension in an additional attribute:
var otherReference = {};
$(document).ready(function () {
$('.nav').find('li').each(function () {
var me = $(this).attr('class');
otherReference[me] = me + "." + $(this).attr("extension");
});
});
Better would be to simply put the page reference in a data element:
<li class="myli" data-pagetoload="about.html">Howdy</li>
$(".nav li").click(function () {
loadPage($(this).data("pagetoload"));
});

Categories