serv-bot 22
serv-bot 22

Reputation: 1298

Why won't my Javascript functions work?

I'm trying to edit this JQuery code to work with a PHP, but for some reason, the javascript is not working properly.

This is the javascript:

function sel(x){
    $(this).stop().animate({height:x},{queue:false, duration:600, easing: 'easeOutBounce'})
}
function desel(){
    $(this).stop().animate({height:'50px'},{queue:false, duration:600, easing: 'easeOutBounce'})
}

Here is part of the PHP:

    foreach($marcas as $mar){
        foreach($modelos["$mar"] as $mod){
            $tam["$mar"]=$tam["$mar"]+20;
    }
    foreach($marcas as $mar){
        $aux=$tam["$mar"];
        echo "<li style='height: $aux px' onmouseover='sel($aux);' onmouseout='desel();'> <p>$mar</p>";
        foreach($modelos["$mar"] as $mod){
                echo "<p class='subtext'>$mod</p>";
        }
        echo"<br/></li>";
    }

Of course, the libraries are both included over the JS code I typed out here, and all the PHP arrays work as intended.

Here is the HTML output on a test run.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 

    <title>Smooth Animated jQuery Menu</title> 

    <link rel="stylesheet" href="animated-menu.css"/> 

    <script src="http://jqueryjs.googlecode.com/files/jquery-1.3.js" type="text/javascript"></script> 
    <script src="js/jquery.easing.1.3.js" type="text/javascript"></script> 
    <script type="text/javascript"> 
    function sel(x){
        $(this).stop().animate({height:x},{queue:false, duration:600, easing: 'easeOutBounce'})
    }
    function desel(){
        $(this).stop().animate({height:'50px'},{queue:false, duration:600, easing: 'easeOutBounce'})
    }
    </script> 
</head> 

<body> 
<ul> 
<li style='height: 80 px' onmouseover='sel(80);' onmouseout='desel();'> 
  <p>VolksWagen</p>
  <p class='subtext'>Bora</p>
  <p class='subtext'>Beetle</p>
  <p class='subtext'>Jetta</p>
  <p class='subtext'>New Beetle</p>
  <br/>
</li>
<li style='height: 20 px' onmouseover='sel(20);' onmouseout='desel();'>
  <p>Jeep</p>
  <p class='subtext'>Cherokee</p>
  <br/>
</li>
<li style='height: 20 px' onmouseover='sel(20);' onmouseout='desel();'>
  <p>Dodge</p>
  <p class='subtext'>Ram 3500</p>
  <br/>
</li>
</ul> 
</body> 
</html> 

Upvotes: 0

Views: 682

Answers (5)

Scott R
Scott R

Reputation: 602

Your functions aren't defined in the global scope, so your <li> elements have no function to call. By putting them in the $(document).ready load function, sel and desel are only defined in that scope, so once that function exists, nothing else has access to them anymore.

Michael Grassman's solution will not fix the problem; defining sel and desel in the global scope won't address the root issue, which is your reference to $(this) in each function. You would need access to the event object, which isn't passed when onmouseover is defined as you've done it, or the element itself, which you aren't passing as an argument to sel or desel. You would need to define the handlers as onmouseover="sel(this,80)" (or whatever number it is), and define function sel(obj,x){ $(obj)... } instead. Though it will work, don't do that. jQuery's event handling functions are a much better alternative.

Patrick dw's solution will work. Since your page content is not dynamic (i.e. the <li> elements never change), you can do this:

$(document).ready(function()
{
  $('li').hover(
    function(){ $(this).stop().animate({height:'auto'},{queue:false, duration:600, easing: 'easeOutBounce'}) },
    function(){ $(this).stop().animate({height:'50px'},{queue:false, duration:600, easing: 'easeOutBounce'}) }
  );
});


I used height:'auto' in the mouseenter above because it looks like you are attempting to restore the height; using 'auto' dynamically recalculates full height. If you want to use a height you set, try using an expando property or the jQuery.data functions to store the desired height on your <li>s.

Upvotes: 1

Steve-O-Rama
Steve-O-Rama

Reputation: 255

The document.ready really isn't a problem here. I think you should use jquery all the way and not define the function calls in your li's if you can. This ended up working for me:

        $(function(){
            $('body ul li').hover(function(){
    var newheight = (Number($(this).css('height').replace('px',''))*5)+'px';
                $(this).stop().animate({
                    height: newheight
                }, {
                    queue: false,
                    duration: 600,
                    easing: 'easeOutBounce'
                });
            }, function(){
                $(this).stop().animate({
                    height: '50px'
                }, {
                    queue: false,
                    duration: 600,
                    easing: 'easeOutBounce'
                });
            });
        });

Which will apply the effect to all li's on the page. You can alter the selector to get more specific or have various heights defined, etc.

Upvotes: 0

Cristian Sanchez
Cristian Sanchez

Reputation: 32097

Since you defined those functions inside the document ready event handler, they're not in the global scope, and not accessible by the rest of the script. Move those function definitions to the "top level" of the script.


Your functions may not be bound to the right context (this) when they are being executed. Try passing the element as an argument.

function sel(x, elem){
    $(elem).stop().animate({height:x},{queue:false, duration:600, easing: 'easeOutBounce'})
}
function desel(elem){
    $(elem).stop().animate({height:'50px'},{queue:false, duration:600, easing: 'easeOutBounce'})
}

And then change in your PHP script:

onmouseover='sel($aux);' onmouseout='desel(); 

to:

onmouseover='sel($aux, this);' onmouseout='desel(this);'> 

Upvotes: 1

user113716
user113716

Reputation: 322452

Is there a reason you're using inline handlers?

I'd get rid of those, and use jQuery to set the handlers.

<li style='height: 20 px' number = '20'>...</li>

jQuery

$(document).ready(function() {
    $('li').hover( function() {
        var x = $(this).attr('number');
        $(this).stop().animate({height:x},{queue:false, duration:600, easing: 'easeOutBounce'})
    },
    function() {
        $(this).stop().animate({height:'50px'},{queue:false, duration:600, easing: 'easeOutBounce'})
    });
});

If the number is just the initial height, you could do this:

$(document).ready(function() {
    $('li').each(function() {
           // Get int value of inline "height" property
        var x = parseInt(this.style.height);
        $(this).hover( function() {
            $(this).stop().animate({height:x},{queue:false, duration:600, easing: 'easeOutBounce'})
        },
        function() {
            $(this).stop().animate({height:'50px'},{queue:false, duration:600, easing: 'easeOutBounce'})
        });
    });
});

Upvotes: 3

Michael Grassman
Michael Grassman

Reputation: 1935

Not sure why you are adding the document.ready.

function sel(x){
    $(this).stop().animate({height:x},{queue:false, duration:600, easing: 'easeOutBounce'})
}
function desel(){
    $(this).stop().animate({height:'50px'},{queue:false, duration:600, easing: 'easeOutBounce'})
}

should work fine since your onmouseovers and onmouseout are calling the functions.

Document.ready runs code on document loaded.

Upvotes: 0

Related Questions