silvestreh / onscreen Goto Github PK
View Code? Open in Web Editor NEWA light library that does stuff when the matched elements enter or leave the viewport
License: MIT License
A light library that does stuff when the matched elements enter or leave the viewport
License: MIT License
Sorry that I write here but i could not find another place.
I wanted to use your jQuery Plugin but i have no idea how. I downloaded the zip file but i cant find which javascript file i have to include into my project.
I dont use npm and i have no idea about npm and no time to work through a new program/framework or what ever npm is.
Could you help me out there?
Thank you for this wonderfull plugin, I've had to add those lines inside checkPos function to retrieve the correct position relative to container, given that my elements are inside relatively positioned divs which are descendants of the scrolled Container.
Please correct me if i've mistaken on something,
var $elAncestor = $el.offsetParent();
var i = 0;
while ((i < 5) && ($elAncestor[0] !== $container[0])){
i++;
var pos = $elAncestor.position();
elTop += pos.top;
elLeft += pos.left;
$elAncestor= $elAncestor.offsetParent();
}
The check
function should call inContainer
instead of inViewport
.
Is there any way to remove onScreen from a specific element?
For example, my page is divided into sections and they all have the same class 'log_entered_viewport'. What I want is that only the first time they enter the viewport that onScreen will be triggered and I will log the event. If the users scrolls up and down the page and the particular section enters the viewport, then I only want it to be triggered once.
Hi. This code runs without an interval. Where is my mistake?
var intervalId = setInterval(_timeineSlider.goToNextSlide(), 5000);
$('.timeline').onScreen({
doIn: function() {
intervalId
}
});
Hi,
I'd like to differ the tollerance. I'd like to animate elements after passing some pixels (eg tolleranceIn: 250), and toggle class right after going outside the viewport (tolerace : 0)
Are you interested in PR? It will brake the API compatibility. "Tolerance" option will be replaced with toleranceIn and toleranceOut.
Hi Silvestre,
quite a beatiful OnScreen you made ๐ฅ
Could it be possible to pass the event type into the callback invocation? This would have saved us from making 2 callback for 2 events, whereas there could be the only one callback. Though this does not deny 2 callback anyhow.
Now the use case looks like:
var os = new OnScreen();
os.on('enter', 'footer', cbEnter);
os.on('leave', 'footer', cbLeave);
function cbEnter(elt) {
console.log('process `enter` event');
addClass(elt, 'onScreen');
console.log(elt + " enters the screen");
// etc.
}
function cbLeave(elt) {
console.log('process `leave` event');
removeClass(elt, 'onScreen');
console.log(elt + " leaves the screen");
// etc.
}
With event name
available from within callback it could look a bit shorter and easier to read:
var os = new OnScreen();
os.on('enter', 'footer', cbProcessOnScreenEvent);
os.on('leave', 'footer', cbProcessOnScreenEvent);
function cbProcessOnScreenEvent(elt, osevt) {
console.log(); 'process '+ osevt + ' event';
osevt === `enter` ? elt.addClass('onScreen') : elt.removeClass('onScreen');
console.log(elt + ' ' + osevt + ' the screen');
}
Notice osevt
event name passed into the callback.
We replace two named callbacks with one, simplify the code a lot, delete repeating parts, and make it more readable / maintainable.
What do you think?
Best regards,
Val
Hello,
is there a way to trigger doIn
function on init ? E.g : i have a gallery with multiples items, i'd like to animate these items when I init onScreen, and then, on scroll with the usual way :)
I think onScreen triggers only on scroll ? and not at init ?
Thanks :)
The following variables are undefined and will be created on the global window
object:
winWidth
winHeight
winBottom
winRight
elHeight
elWidth
elTop
elLeft
scrollLeft
You are declaring scrollTop
correctly, atleast for now. However, the fact that it has a trailing comment that specifically mentions "probably not needed" does not bode well.
Could you add Typescript support?
For example lets say I have a div that the plugin says is onScreen (example: div#main) which itself contains a list of items.
I notice in two instances... for example if I cover the div#main with another div making div#main "offScreen" and if I replace div#main with another div via backbonejs or jquery .show, it does not trigger "offScreen" state or "doOut".
So my question is if we can programmatically give a div ".offScreen" screen state and thus triggering "doOut".
It would be a nice feature to have, also thanks for this solid library.
First of all, thanks for this great tool, it is working great!
Today I've been analysing a project with the "Audits" tool of Chrome Dev Tools, and it suggests to implement "Passive Event Listeners" to improve scrolling performance:
https://developers.google.com/web/tools/lighthouse/audits/passive-event-listeners
Might be something worth looking into?
Best wishes!
It might be a good idea to rewrite plugin with support of Intersection Observer.
In short, it's more performant than current implementation.
This is a feature request, not an issue.
I understand why debounced scrolling is used, but sometimes you want events triggered even while scrolling. Sorry, but I'm not good with git, so what I did was create a handleScroll
function to be called instead of debouncedScroll
. If the debounced
option === false
then handleScroll calls eventHandler
immediately. If debounced
is not false
then it does a return debouncedScroll.call(this);
.
I think having the option to not use debounced scrolling would be a useful addition to this great library.
/**
* Determines whether scroll event should be fired immediately or debounced
*
* @return {void}
*/
function handleScroll() {
var _this = this;
var debounce = this.options.debounce;
if (debounce === false) {
return function () {
eventHandler(_this.trackedElements, _this.options);
}
}
else {
return debouncedScroll.call(this);
}
}
I have written a super simple angular wrapper directive. I think this might be helpful for angular guys.
angular.onscreen.js
(function () {
angular.module('on-screen', []).directive('onScreen', function () {
return {
restrict: 'A',
link: function (scope, el, attrs) {
el.onScreen(scope.onScreen);
}
};
});
})();
And here's how you use it:
<html data-ng-app="main-app">
...
<div on-screen="onScreen">I'm here!</div>
<script>
(function () {
var app = angular.module('main-app', ['on-screen']);
app.controller('main-control', function ($scope) {
$scope.onScreen = {
container: window,
direction: 'vertical',
doIn: function () {
console.log('I am in.');
},
doOut: function () {
console.log('I am out.');
},
tolerance: 0,
throttle: 50,
toggleClass: 'onScreen',
lazyAttr: null,
lazyPlaceholder: 'someImage.jpg',
debug: false
};
});
})();
</script>
...
</html>
In my application, I only have need for using the enter hook. The off
method attempts to create callback arrays for enter and leave hooks, without any safeguard for the scenario where one doesn't have any callbacks for that hook. Thus it throws this error:
Uncaught TypeError: Cannot convert undefined or null to object
A potential solution would be something like this:
function off(event, selector, handler) {
const enterCallbacks = Object.keys(this.trackedElements[selector].enter || {});
const leaveCallbacks = Object.keys(this.trackedElements[selector].leave || {});
This way Object.keys()
returns an empty array instead of an error if one of these hooks isn't used. There might be a more fundamental way to approach this, such as ensuring the trackedElements[selector] has this property defined in the case one isn't provided, but this is a possible solution.
I have forked the repo and can make the change, but I can't get to it until, at the earliest, tomorrow. If it's faster or easier for you or someone else to do it, be my guest.
Hello,
I have this script to monitor when a element will enter or leave the viewpoint.
$(function() {
var os = new OnScreen();
var header = $('.top-bar');
os.on('enter', '#header', function() {
console.log('enter');
});
os.on('leave', '#header', function() {
console.log('leave');
});
});
The markup is this:
<header id="header">
<div class="row align-right top-bar animated">
<div class="column">
<div class="sub-column">
...
</div>
<div class="sub-column">
...
</div>
</div>
</div>
</header>
Case 1 (issued)
.sub-column {
display: flex;
align-items: center;
}
On page loading enter
event was triggered. I scroll the page and the leave
event do not triggers. I return to top of the page and enter
triggers, so I scoll down for the second time and only not the leave
event triggers. After this point all entering and leaving triggers.
I register the same behavior when I try to use a table-like layout:
.sub-column {
display: table-cell;
}
Case 2
.sub-column {
display: block;
}
On page loading enter
event was triggered. I scroll the page and the leave
event was triggered. The behaviour repeats as expected, so it's working fine.
Hi, thanks for the awesome library. I need help though with the library's integration with React. Seems like the events are not propagating as well as expected in React. enter
fires as soon as the component mounted and leave
never fires. Is there a way to make this work with React? Cheers!
I have $(target).onScreen('remove'); call at the end of my doIn method - but the doIn gets called every time the element is on screen (I'm trying to just get it to fire the first time)
Hello. Im using the latest version (1.2.0) and wanted to use OnScreen
on my canvas elements which are containing charts from chart.js
. When i just use this code:
os.on("enter", "canvas", function(element) {
console.log("canvas enter: " + $(element).attr("id"));
});
os.on("leave", "canvas", function(element) {
console.log("canvas leave: " + $(element).attr("id"));
});
It is working correctly, the ouput is:
canvas enter: evaluation_combined_canvas_0
canvas leave: evaluation_combined_canvas_0
canvas enter: evaluation_combined_canvas_1
When i now add the Chart.js
part:
os.on("enter", "canvas", function(element) {
console.log("canvas enter: " + $(element).attr("id"));
var config = getConfigCombined($(element).attr("id"));
var context = $(element);
var combined = new Chart(context, config);
});
os.on("leave", "canvas", function(element) {
console.log("canvas leave: " + $(element).attr("id"));
});
The output is:
24 canvas enter: evaluation_combined_canvas_0
canvas enter: evaluation_combined_canvas_1
canvas enter: evaluation_combined_canvas_0
canvas enter: evaluation_combined_canvas_1
canvas enter: evaluation_combined_canvas_0
canvas enter: evaluation_combined_canvas_1
canvas enter: evaluation_combined_canvas_0
[โฆ]
The "enter" now is called on every scroll.
Hello,
it sounds like a newbie question but.. i'd like to try this new version of OnScreen.js but i'm unable to find the dist
folder and the required file that you mention in the README "OnScreen.umd.js"..
in any case, thanks for your work, i can't wait to use it :D
Hi I need some help. I have installed the package with 'npm i onscreen --save'. How do implement this to a page? I have imported this on my page
import { OnScreen } from 'onscreen';
ngAfterViewInit() {
const os = new OnScreen({
tolerance: 0,
debounce: 100,
container: window
});
console.log(os);
}
I'm getting error
WEBPACK_IMPORTED_MODULE_4_onscreen.OnScreen is not a constructor
How do I actually use this?
Hi,
We are getting this when we run bower install. Any idea why?
I've been using this script via my bower dependency but since the upgrade, I can no longer do that. Can you add your final dist file into the repo so bower can pull it down?
Hi,
I installed onScreen using below command successfully:
npm install onscreen --save
But I failed to bundle onScreen with babel.
The error is:
Error: Cannot find module 'OnScreen'
at Function.Module._resolveFilename (module.js:438:15)
at Function.Module._load (module.js:386:25)
at Module.require (module.js:466:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (gulpfile.babel.js:23:1)
at Module._compile (module.js:541:32)
at loader (/Users/zhenyu/Development/nodetest/frontend/node_modules/babel-register/lib/node.js:158:5)
and below is my usage, the same as the README:
import OnScreen from 'OnScreen';
Bower does not have any versions available for this repository.
Running a bower info onScreen produces the following:
{
name: 'onScreen',
description: 'A jQuery plugin that does stuff when the matched elements are visible (as inside the viewport).',
main: 'jquery.onscreen.js',
keywords: [
'jquery',
'onscreen',
'screen'
],
authors: [
'Silvestre Herrera'
],
dependencies: {
jquery: '*'
},
license: 'MIT',
homepage: 'https://github.com/silvestreh/onScreen',
ignore: [
'**/.*'
]
}
No versions available.
I believe the issue is that you need to create a 0.1.0 tag in your git repository for bower to pull.
See http://stackoverflow.com/questions/19456091/bower-register-new-version
https://github.com/silvestreh/onScreen/blob/master/lib/methods/debounced-scroll.js#L16 should be debounce
not throttle
.
Hello :)
I've been using this script on different projets, i found it very usefull !
However i never used it with ajax loaded content... Any help to "watch" some divs which were loaded after the script init ? (they all have the same class ".reveal")
Many thanks :)
I'm not sure if this is expected functionality or a bug. I initialize my OnScreen object using a container. In this case my container is a jQuery object named wrap
. As soon as the enter
event is set, all elements in my HTML with the class .reveal
get immediately triggered, even if they are not inside of my container element. Is this correct? I assumed that only elements inside the container would be handled.
var os = new OnScreen( {
tolerance : 100,
debounce : false,
container : wrap.get( 0 ),
} );
os.on( 'enter', '.reveal', function( elem, evt ) {
$( elem ).addClass( 'active' );
} );
The bower package for OnScreen is outdated, investigate how to integrate it in the build/publish tasks or get rid of it.
Hi,
I am trying to add stop some animations when those elements are not in viewport. I try this using your plugin with the on.leave event and it does not work. However, the on.enter event is working fine. Is this a bug?
Thanks!
It looks like the cssClass and doIn are being fired on page load, not when the elements are scrolled into view. And the events are again only fired after scrolling past and back up, not when scrolling down.
Is anyone else seeing this?
I like what you have done and thank very much. Will keep using this.
Cheers
Hey there
formerly, onScreen was a theme? I wanted to know is there any update for it?!
Make it so checkPos() can be triggered manually.
I'm using this (awesome) plugin to handle showing of content within a scrolling div on a page, but when the page is resized (which resizes the subsequent container) it doesn't trigger a new load.
I just loaded the js from unpkg -
<script type="text/javascript" src="https://unpkg.com/onscreen/dist/on-screen.umd.min.js"></script>
and then used the following code:
var os = new OnScreen();
os.on('enter', '#elementId', (element, event) => {
element.style.backgroundColor = 'red';
});
The div immediately turns red on page load if it's visible in the viewport. If the element is not in the viewport, scrolling to it effects no changes.
It would be great to have an example of how to use the os.destroy() functionality, it is not clear from your documentation.
Being able to set a tolerance on doOut would be a nice enhancement for this.
If you attach and destroy onScreen regularly in a page, it will slowly build up a list of listeners for DOM mutations.
If I do a :
bower install onScreen
I get the follow error message:
ENOTFOUND Package onScreen not found
In my bower.json I have the following dependency:
"onScreen": "*"
Really liking the plugin, but I did notice some unexpected behavior when dealing with anchor/hashes. This Gist shows that when you try to access it with filename.html#before8 you get unexpected results.
Since the named anchor is before the last box, one would expect doIn to fire in the context of the last element only (the only one after the anchor). E.g. the log should read '8'. Instead it is behaving unusually across browsers:
Firefox's response may be rational since it does show a sliver of box 7 at the top of the window.
Can be an easy way to do an trigger just once per element on the "enter" event.
I'm using something like this:
<p class="anim">foo</p>
<p class="anim">foo</p>
os.on('enter', '.anim', (element) => {
element.style.color = 'red'
})
I saw the issue #29 , but I'm not using jQuery.
Can this become an "enhancement"
I was testing one of my projects with this plugin in a IOS and the listeners are not working..
I'm currently hacking on this now and trying to add support for .on({'touchmove'
so that doIn()
and other methods can be fired while scrolling on a touch device, instead of after the user stops scrolling. Were you thinking about implementing anything like this in the future? Thanks for a sweet tool, nonetheless ๐
Now only the last callback is executed.
I tried onScreen with Browserify, but I get this error.
Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
Code
let onScreen = require('../vendors/jquery.onscreen');
$('.speakers').onScreen({
container: window,
direction: 'vertical',
doIn: function() {
// Do something to the matched elements as they come in
},
doOut: function() {
// Do something to the matched elements as they get off scren
},
tolerance: 0,
throttle: 50,
toggleClass: 'onScreen',
lazyAttr: null,
lazyPlaceholder: 'someImage.jpg',
debug: false
});
I've come across an issue where I need to unbind obScreen, but there is no functionality to remove bindings in the plugin.
Details:
I have a very large table, where I want to display data within table cells on scroll. There is a filter function that adds/removes a 'hidden' class to the rows. However, because the onScreen call was bound on document ready, when all rows were visible, the hidden rows are still actioned upon even though they're hidden, creating a horribly slow response.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.