Function not working creating a variable and using jquery? - javascript

I have a function which changes the width of some images. This happens when I hover over a different div in a different function. For some reason the the called function only performs some lines of code and then it stops.
function hey()
{
alert(0);
var $imgContent = ('.imgContent');
$imgContent.css("width","10%");
alert(2);
}
var $content = $('.content');
$content.mouseenter(function() {
$content.removeClass('full').addClass('partial');
$(this).addClass('full').removeClass('partial');
$(this).find('.img1').css('display','none');
$(this).find('.img2').css('display','');
if($(this).hasClass('cont1')){
alert(1);
hey();
}
if($(this).hasClass('cont2')){
}
if($(this).hasClass('cont3')){
}
if($(this).hasClass('cont4')){
}
}).mouseleave(function(){
$(this).find('.img1').css('display','');
$(this).find('.img2').css('display','none');
$(this).removeClass('full').addClass('partial');
});
In the mouseenter() function when I check if $(this).hasClass('cont1') then I perform an alert, which works. After that I call on function hey(). This is where my problem arises. After calling function hey() i perform another alert(0) , which also works. But the lines of code after that do not get executed and the last alert(2) doesn't work either.

There is an error in your code.
Replace:
var $imgContent = ('.imgContent');
With
var $imgContent = $('.imgContent');

You have a mistake in your jquery object definition.
Per jQuery():
jQuery() — which can also be written as $() — searches through the DOM for any elements that match the provided selector and creates a new jQuery object that references these elements
so in your case you should have:
var $imgContent = $('.imgContent');
$imgContent.css("width","10%");
Also, it's important to note that in your .mouseenter() function you refer to:
$content.removeClass('full').addClass('partial');
$(this).addClass('full').removeClass('partial');
$content and $(this) both refer to the same object, so in essence these lines are pointless.

Related

Function is being called without trigger event

I have a function that I want to use in order to expand menus in various places. I expect it to be triggered on a click of menu associated button, but at the moment it is being called on page load (I assume from within document ready), and class 'expanded' is added without clicking on a buton. I am confused to why this happens, as it should be called .on('click' ..
jQuery(document).ready(function ($) {
'use strict';
$('#btn-expand-mobile-nav').on('click', showMenu('#side-navigation'));
});
function showMenu(menu) {
var x = $(menu),
y = 'expanded';
if (x.hasClass(y))
x.removeClass(y);
else
x.addClass(y);
}
You are calling the function immediately. Instead defer the execution using an anonymous function:
$('#btn-expand-mobile-nav').on('click', function(){
showMenu('#side-navigation')
});
If there were no parameters you could have done this:
$('#btn-expand-mobile-nav').on('click', showMenu);
Simplistic explanation for #skobaljic:
By using the function name alone, you are pointing at the variable showMenu and saying call this later as a function.
By using function(){} you are saying, here is a temp variable, containing a function, that you can call later.
e.g. it is the same as:
var temp = function(){
showMenu('#side-navigation')
}
$('#btn-expand-mobile-nav').on('click', temp); // No parenthesis on temp
As #Dave Newton rightly points out, this can be simplified using toggleClass:
$('#btn-expand-mobile-nav').on('click', function(){
$('#side-navigation').toggleClass("expanded");
});

My jquery Animation doesn't work after ajax call

I'm trying to get my animation to work on after an ajax call has been made. It works fine when the user lands on the page. But if the user navigates back to the front page the animation will not run. I'm pretty new to Jquery, could you give me some hints?
I think it has something to do about .on but I'm not sure about the syntax if so. Any help would be greatly appreciated.
This is the code:
<script type="text/javascript">
(function() {
var quotes = $(".quoteName");
var quoteIndex = -1;
function showNextQuote() {
++quoteIndex;
quotes.eq(quoteIndex % quotes.length)
.fadeIn(3000)
.delay(12000)
.fadeOut(3000, showNextQuote);
}
showNextQuote();
})();
</script>
It seems that, when you make that AJAX call, you update (and by that I mean removing the current DOM nodes contained in the quotes object and creating new ones). If you do this, when you anitame the nodes in the quotes object, nothing will happen, becauser they no longer belong to the DOM you're seeing. jQuery objects don't have 'live updates', they don't change to reflect the changes in your DOM.
What you need is to make this call again after your AJAX request completes, to update the quotes object:
quotes = $('.quoteName');
Of course, your 'quotes' object is not global, so you might not be able to update it if your AJAX call is not inside the scope of the anonymous function where you're defining the code you've posted.
As far as I can see you have an Immediately Invoked Function Expression:
(function() {
})();
every variable and function declaration you put inside (like showNextQuote()) will not be accessible from other functions outside of it.
(function() {
function showNextQuote(arg) {
alert( arg );
}
showNextQuote('A');
})();
showNextQuote('B'); // ReferenceError: showNextQuote is not defined
One other thing is that your var quotes = $(".quoteName"); selector might get no results cause the DOM was not ready to be parsed by JS and for jQuery to catch your elements.
jQuery( function($) { // DOM is now ready and the $ alias secured.
var quotes = $(".quoteName");
var quoteIndex = -1;
function showNextQuote() {
++quoteIndex;
quotes.eq(quoteIndex % quotes.length).fadeIn(3000).delay(12000)
.fadeOut(3000, showNextQuote);
}
showNextQuote();
// other functions here
$('selector').on('some event', 'dynamicSelector', function(){
showNextQuote(); // will work
// other stuff here?...
});
});
Another hint would be that if you populate your DOM with new elements you might want to re-catch them to update the quotes.length

function scope in jQuery

I have this code in <script> tags at the top of my HTML file.
$(document).ready(function()
{
$('#scrollbar1').tinyscrollbar();
$('a.jqtree_common').click(updateScrollbar());
});
$(function updateScrollbar()
{
var oScrollbar = $('#scrollbar1');
oScrollbar.tinyscrollbar();
oScrollbar.tinyscrollbar_update();
$('a.jqtree_common').click(updateScrollbar());
});
But for some reason when I run this, it says updateScrollbar() is undefined within (document).ready. When I try to define updateScrollBar() inside of (document).ready then updateScrollBar() gets caught in some kind of endless loop.
My question is twofold:
What can I do to make updateScrollBar() defined within the scope of (document).ready?
Is there a better way to assign this function to the 'a.jqtree_common' elements? They are created dynamically at runtime, and modified as the webpage is used. I want the function to run every time one of them is clicked.
I'm using tiny scrollbar and jqtree
EDIT: I want the $('a.jqtree_common').click(updateScrollbar); assignment to be made every time the scrollbar is updated, since I believe clicking on a 'a.jqtree_common' element creates more 'a.jqtree_common' elements.
Pass the function reference as the callback, instead of the result of the function in Click event. () will invoke the function and set the result as a call back which inturn calls updatescrollbar inside it again and goes in an infinite loop.
$(document).ready(function()
{
$('#scrollbar1').tinyscrollbar();
$('a.jqtree_common').click(updateScrollbar);
});
function updateScrollbar()
{
var oScrollbar = $('#scrollbar1');
oScrollbar.tinyscrollbar();
oScrollbar.tinyscrollbar_update();
//$('a.jqtree_common').click(updateScrollbar);
}
Okay, I know there are a lot of hats in the ring at this point, but here's my entry just the same...
//IMMEDIATELY-INVOKED FUNCTION EXPRESSION (IIFE)
// Used for privacy/variable scoping
(function(){
//bind init function to dom-ready event
$(init); //same as $(document).ready(init);
//initialize event bindings for page
function init() {
//initialize scrollbar
$('#scrollbar1').tinyscrollbar();
//click binding for tree
$('a.jqtree_common').click(updateScrollbar);
//assuming you want to run the updateScrollbar on page load
//in addition to clicks
updateScrollbar();
}
//handles scrollbar updates
function updateScrollbar() {
//assuming the tinyscrollbar() initialization only needs
//to happen once, inside the initialization event.
$('#scrollbar1').tinyscrollbar_update();
}
}());
The structure above is pretty much how I work through things... I do my variables first, then event bindings at the top, and have my function declarations below. This works because of function hoisting (in compilation of the JS, function declarations are moved to the top), this doesn't work with function assignments (ex: var x = function(){...}), then I wrap the whole thing inside an IIFE. I find that this structure provides easier readability and comprehension. I don't like putting my bindings at the bottom, as I find you have to go over a lot to get to what you are looking for.
Try this code:
$(document).ready(function() {
var updateScrollbar = function () {
var oScrollbar = $('#scrollbar1');
oScrollbar.tinyscrollbar();
oScrollbar.tinyscrollbar_update();
};
$('#scrollbar1').tinyscrollbar();
$('a.jqtree_common').click(updateScrollbar).click();
});
To bind elements loaded later we must use this .on( function
$(document).ready(function(){
$('#scrollbar1').tinyscrollbar();
$(document).on("click","a.jqtree_common", updateScrollbar);
});
function updateScrollbar(){
var oScrollbar = $('#scrollbar1');
oScrollbar.tinyscrollbar();
oScrollbar.tinyscrollbar_update();
}
and if you want the scope limitation then declare function within the block
$(document).ready(function(){
$('#scrollbar1').tinyscrollbar();
$(document).on("click","a.jqtree_common", updateScrollbar);
function updateScrollbar(){
var oScrollbar = $('#scrollbar1');
oScrollbar.tinyscrollbar();
oScrollbar.tinyscrollbar_update();
}
});
This is what ultimately worked for me:
$(document).ready(function()
{
$('#scrollbar1').tinyscrollbar();
$('a.jqtree_common').click(updateScrollbar);
function updateScrollbar()
{
var oScrollbar = $('#scrollbar1');
oScrollbar.tinyscrollbar();
oScrollbar.tinyscrollbar_update();
$('a.jqtree_common').click(updateScrollbar);
}
});

Anonymous function on page load

I'm trying to get better with JavaScript and learn how to utilize my code in functions and keep everything clean. I'm trying to run a function on page-load...
var setColors = function(){
this.init = function(){
$.getJSON('js/colors.json', function(colors) {
$.each(colors, function(i, colors) {
$('<li>', {
text: colors['color'],
'name' : colors['color'],
'data-hex' : colors['hex'],
'data-var' : colors['var']
}).appendTo('#picker');
})
});
}
}
(This is not a color-picker, just a list of colors)
I want setColors() to be executed as soon as the page starts. I read that an anonymous function runs automatically, but this one isn't, I also tried...
$(function(){
setColors();
});
Below the setColors() function and that isn't working ether (The page is just blank). What am I doing wrong and how do I get my function to run on page load? I'm trying to learn so an explanation would be great.
Anonymous functions are not run immediately, you're thinking of Immediately Invoked Function Expressions which happen to often use an anonymous function.
To fix your code:
a) get rid of the this.init function wrapper within the "object" - you're not using it and this.foo only makes sense if you're using new to instantiate an object:
function setColors() {
return $.getJSON(...);
}
Note that returning the $.getJSON() result allows you to register additional deferred object handlers, register error handlers, etc.
b) call the above function in a document.ready handler (which you must do, since the AJAX callback modifies the DOM).
$(setColors);
NB: the latter is a legal way of calling this handler - jQuery will automatically register any function that you pass this way as a document.ready handler. It's similar to writing:
$(function() { setColors() })
but without the extra (useless) function wrapper.
To have that run once the DOM is initialized, you can put it in a ready listener (jQuery):
$(document).on('ready', function() {
setColors();
});
If you want the function to run automatically as soon as it is encountered in the js, after the } that ends the function, add ();
Something like:
function setColors() {
// Code
}();
setColors doesn't return the next function, or call it at the end. YOu could change it to look like:
var setColors = function(){
this.init = function(){
$.getJSON('js/colors.json', function(colors) {
$.each(colors, function(i, colors) {
$('<li>', {
text: colors['color'],
'name' : colors['color'],
'data-hex' : colors['hex'],
'data-var' : colors['var']
}).appendTo('#picker');
})
});
}
init(); // <--- change
}
Which would do the trick for you. You don't even need to "return it" either since the init function itself doesn't return anything, so you could just call it.

JavaScript doesn't see a variable outside function

I have this function:
$(function ($) {
...
});
var getNotifyBar = $(".NotifyBar");
function showNotify(text) {
getNotifyBar.hide().find(".text").html(text).end().slideDown();
}
And when I use function showNotify(text) nothing happens. But when I put it in the JavaScript console (of the browser) it works.
More than likely this is running before all the elements with class NotifyBar are rendered
var getNotifyBar = $(".NotifyBar");
Which means that it is empty when you try to use it later. you should do this instead:
var getNotifyBar;
$(function ($) {
getNotifyBar = $(".NotifyBar");
});
Now it should be properly loaded. Next, you need to remember that getNotifyBar is a reference to a jQuery object already loaded from a selector. As such, you do not need to wrap it in $(). You should make this change:
function showNotify(text) {
getNotifyBar.hide().find(".text").html(text).end().slideDown();
}
Your code has no chance of working now and works from console, because when you run it in console it's after the DOMReady. Put the code in place of your 3 dots in the example and it will work, because:
$(function($){
//code here
})
will run the code after DOMReady

Categories

Resources