1

Is there a better way to monitor a variable for change and trigger a function at certain value?

At the moment I have this -

$(window).on('scroll', function() {
    if(scrolledYet == "ready" && positionNow < 20){
        fadeOutIntro();
        scrolledYet = "yes"; 
    }
    if(scrolledYet != "ready" && positionNow < 840  && positionNow > 20 ){
        $('.logoBlock,.introScrollIcon, .introText').fadeIn('700')
           setTimeout(function() {  $('#nav').fadeIn('1000');},1000);
          setTimeout(function() {introOnOff = "on";},100)
    }
});

the positionNow variable is set in another function and stores the current scroll position, is there a better way to structure this script

4
  • Well, you already are monitoring it and that's why you are checking it's value while scrolling. Aren't you? Commented Jan 8, 2013 at 16:16
  • your scroll-position can be found in {element-with-scrollbar}.scrollTop(), see also here developer.mozilla.org/de/docs/DOM/element.scrollTop and api.jquery.com/scrollTop Commented Jan 8, 2013 at 16:21
  • see also this solution: stackoverflow.com/questions/14202770/… Commented Jan 8, 2013 at 16:22
  • yes - but in the current setup it seems to react unpredictably - if I alter the script so it will only trigger each set of instructions once in each scenario and i alert the poistionnow variable in the second function - it has a different height figure each time - which makes me think that there must be a better way to monitor the variable as it doesnt seem very accurate? Commented Jan 8, 2013 at 16:22

3 Answers 3

1

Why not use event binding and propagation to monitor variable value, and if your desired value is reached, then trigger another event? The basic idea is below using a demo "object" but you can apply it to your "positionNow" or any other kind of variable for any object that might already have accessible properties (including the "window" object).

e.g.: jsfiddle - http://jsfiddle.net/vepWE/1/

JS:

$("#b").data('myscrollposition', 100);
$("#c").data('myscrollposition', 101);
$("#d").data('myscrollposition', 100);

function f(evt)
{
     $(this).val("desired event triggered");
}

function change(evt)
{
    var m = $(this).data('myscrollposition');
//equivalent to above: var m = $(evt.currentTarget).data('myscrollposition'); 
     if(m == 100)
     {
          $(this).trigger('valuereached');
     }
}

$(".des").on('change', change);
$(".des").on('valuereached', f);
$(".des").trigger('change');

HTML:

<input class = "des" id = "b"></input>
<input class = "des" id = "c"></input>
<input class = "des" id = "d"></input>

NOTE: Also remember that if your element doesn't exist on the page yet, you must use this syntax:

$(".parentcontainer").on("myevent", '.listenforthisalways', function(event){
  alert($(this).text());
});

and it will work even if you add an element with the class of "listenforthisalways" later on in the page (in the above example, only if it is added as a descendant of a container with class "parentcontainer") instead of already having the elements on the page.

Another example that listens for ANY addition of html elements with the class "myFOO" ANYWHERE on the page and binds the event "myevent" to the function "myfunction" for that element even when it is added to your page later, would be the following:

   function myfunction(evt)
   {
     //whatever
   } 

  $(document).on("myevent", '.myFOO', myfunction);

Hope this helps!

Sign up to request clarification or add additional context in comments.

Comments

1

Why not do this all in CSS, it might be faster?

If you have an absolutely positioned invisible element , as the user scrolls over it a hover state will be created which you can trigger your animation. ( you may need to have many of your page elements as a css descendant of this to work right )

If you need to do it in JS there are some things you can do to improve the speed. As you have this now, you are creating new functions every time you scroll. Try to set up your JS so that the browser only has to JIT compile the JS on page load, so refer to those functions as handlers, and you can also do the jQuery css selection only once, in your case your are using an ID so that is probably a pretty fast lookup, but if you did a '[data-name=data-value]', it's actually a pretty slow query.

You could also break this up to trigger two new events on entering and exiting the [20px-840px] region, and then you could debounce them using underscore.js. http://underscorejs.org/#debounce

i know this is pretty high level, and i didn't write specific code, but I hope it helps.

Comments

0

Yes it is, but it's some advanced JavaScript stuff that may not be available everywhere (hint MSIE).

var o = {_positionNow: 1};
Object.defineProperty(o, "positionNow",
                      {get: function() { return this._positionNow },
                       set: function(positionNow) { this._positionNow = positionNow },
                       enumerable: true,
                       configurable: true});

Of course, o can be any context, like window if you like dirty stuff. Or simply search for some KVO (Key Value Observing) patterns if you want to say away from JavaScript 1.8.5 and above.

More documentation about defineProperty.

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.