0

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:

  1. What can I do to make updateScrollBar() defined within the scope of (document).ready?
  2. 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.

10
  • 2
    just remove the $( and ); surrounding your function. The DOM doesn't need to be ready to declare the function. Commented May 28, 2013 at 22:36
  • When using event binding, the function don't need () or it will be called when the browser read that line. Commented May 28, 2013 at 22:37
  • @caps we must use this .on( function for binding dynamic elements Commented May 28, 2013 at 22:46
  • @RohitAgrawal why is that? Commented May 28, 2013 at 22:52
  • instead of bind element it uses a static element such as document e.g. $(document).on( and then it looks for the target and match with he selector provided , so you don't have to bind again and again when that element is added , look my answer Commented May 28, 2013 at 22:56

5 Answers 5

1

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);
}
Sign up to request clarification or add additional context in comments.

4 Comments

@JuanMendes Did not get you?
The scope still needs to be fixed. You need to remove the $( before function updateScrollbar(), as well as the matching );.
@JuanMendes Man probably i was typing when you set teh comment.
This is the closest to the answer that worked for me, except I did not comment out the $('a.jqtree_common').click(updateScrollbar); line.
1

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.

Comments

0

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

5 Comments

$('a.jqtree_common').click(updateScrollbar()); should be $('a.jqtree_common').click(updateScrollbar);
made a minor change to correct your JS, in addition, I tend to rely on function hoisting to put my function definitions below my event bindings, but didn't change this.
Function hoisting wouldn't work in this case. Only the variable updateScollbar gets hoisted, not the value.
I know, would have to refactor to use function updateScrollbar... underneath the binding.
Indeed. BTW: SO-etiquette is only to edit answers/posts for formatting issues or spelling mistakes. If it's a change in code, it's better to leave a comment. In this case, I was OK with the edit, but you can imagine it could lead to a big discussion if I didn't agree with your change and a back-and-forth editing game.
0

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

});

2 Comments

I tried both of these, but neither one of them worked for me.
can i get the fiddle to see
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.