2

Here's the plugin in case anyone finds it useful. http://silvestreh.github.io/onScreen/
Thanks again!


So, I'm trying to write my very first jQuery plugin and I already found my first road block. The plugin is supposed to do something to an element when it's visible (as in the view port area, not CSS visibility)

This is what the plugin looks like:

(function($) {
  $.fn.onScreen = function(options) {
    var self = $(this);

    params = $.extend({
      doIn: function(){
        console.log('on screen');
      },
      doOut: function(){
        console.log('off screen');
      },
      offset: 0
    }, options);

    return this.each(function() {
      var $el = $(this);
      var elTop = $el.offset().top;

      $(window).scroll(function() {
        var pos = $(window).scrollTop();

        if (pos + params.offset >= (elTop - $el.height()) && pos + params.offset < (elTop + $el.height())) {
          params.doIn.call($el[0]);
        } else if (pos + params.offset > (elTop + $el.height()) || pos + params.offset < elTop) {
          if (typeof(params.doOut) == 'function') {
            params.doOut.call($el[0]);
          }
        }
      });
    });
  };
})(jQuery);

And this is how I'm trying to use it:

$(function(){
  $('div').onScreen({
    doIn: function() {
      $(this).stop().animate({
        left: 20
      },500)
    },
    doOut: function() {
      $(this).stop().animate({
        left: 0
      },500)
    }
  });
});

The problem is that $(this) refers to the window object (because of the $(window).scroll() in the plugin) and not the matched elements. What am I doing wrong? How do I tell my plugin that I want to do stuff to the matched elements instead?

Thanks in advance :-)

EDIT: I just created a JSFiddle so you can check it out. http://jsfiddle.net/FBEFJ/3/ EDIT 2: bfavaretto fixed the code. I updated the question with the working code. Thank you!

1 Answer 1

1

The problem is how you're calling doIn and doOut in the plugin. Perhaps the simplest solution is to enforce a this value with Function.prototype.call:

if (pos + params.offset >= (elTop - $el.height()) && pos + params.offset < (elTop + $el.height())) {
    params.doIn.call($el[0]);
} else if (pos + params.offset > (elTop + $el.height()) || pos + params.offset < elTop) {
    if (typeof(params.doOut) == 'function') {
        params.doOut.call($el[0]);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Just tried that. I'm still getting the same results. Here's the output: Uncaught TypeError: Cannot use 'in' operator to search for 'left' in undefined jquery-1.10.2.js:6820
I made a mistake, you should use $el[0] instead of this (answer updated, fiddle too: jsfiddle.net/FBEFJ/4).
Yes! Thank you! I would vote you up if I could (I need 15 reputation). That worked like a charm.

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.