camwiegert / in-view Goto Github PK
View Code? Open in Web Editor NEWGet notified when a DOM element enters or exits the viewport. :eyes:
Home Page: https://camwiegert.github.io/in-view
License: MIT License
Get notified when a DOM element enters or exits the viewport. :eyes:
Home Page: https://camwiegert.github.io/in-view
License: MIT License
It's important for a library like in-view to be able to specify a specific container to be used (not just body).
You might want for example to lazy load images inside a specific div that has a limited height with scrollbars.
What do you think?
Hi,
thanks for the simple and awesome module.
I think the purpose of .once is to trigger something only when i comes into the viewport the first time and not if it leaves and comes into the viewport again.
Something similar to scrollReveals "once" function. But, if i bind inview to multiple dom elements, e.g. I have 3 .item divs in my dom. .once will trigger the function for all .item at the same time. I think instead it should trigger the function .once but for every single .item when it comes into the viewport.
By the way: the module also works perfectly if you dont use native scrolling and instead something like virtual-scroll, which is a great plus!
Currently, in-view grabs innerHeight and innerWidth on every call to inViewport. We should cache that, update on resize, and pass it to inViewport as an argument.
export function inViewport (element, offset = 0) {
let { top, right, bottom, left } = element.getBoundingClientRect();
return bottom > offset
&& right > offset
&& window.innerWidth - left > offset
&& window.innerHeight - top > offset;
}
It doesn't seem possible currently since threshold is set on the function and there's no instantiation happening. If I try to create another "instance" by requiring again and assigning to a different var of course that doesn't work either since it's the same cached function.
Wanted to confirm that this is the case, and if so whether it'd be addressed in the 1.0 API?
I gave IntersectionObserver a shot which supports this since it's an object, but ran into some inconsistent failures in Chrome.. I will say that the API of in-view is far easier to work with in practice than IntersectionObserver was, since it doesn't have much of a notion of exits.
In the readme, it's not so clear how to quickly include this lib via an HTML page. Something like
<script src="https://cdnjs.cloudflare.com/ajax/libs/in-view/0.11.5/in-view.js"></script>
Would be much helpfulness!
Hey,
inView('.someSelector').check();
inView.is(document.querySelector('.someSelector'));
both returns: Uncaught TypeError: Cannot read property 'top' of undefined(…)
I am using Chromium 53.0.2785.92 & latest in-view.min.js
I am getting the following error. how can i fix it?
We need a short README and a gh-pages branch for documentation.
As far as I have seen I think in-view
is just using lodash throttle as a dependency. Is it possible to just use https://www.npmjs.com/package/lodash.throttle
?
As it stands, you can only set the offset globally, but it'd be nice to be able to set an offset in each direction, à la:
inView.offset({
top: 50,
right: 100
bottom: 0,
left: 25
});
Whenever wait 1. 2 days of the same and I hope when vo catch the pokemon he flees
Alguen help me? If bug PFV solve
Using webpack and a vendor chunk which we load async in the head is currently impossible due to the document.body.insertBefore statement requiring the body to be available. Deferring the feature testing to 1st usage would remedy the issue in most cases.
Would it be possible to change the implementation to support such a usage pattern ( when http2 push arrives in all browsers this will be the most likely usage pattern for loading js dependencies prolly so it much add to future proofing the library )
Heelo
Is there a way to introduce HTML5 tag data-attributes to link a div to templates that can be defined in the javascript so the same template is usable by multiple divs?
Thanks
Hey this is pretty cool!
Just thought I'd mention, you list 'dependency free' in the readme, but you do have a dependency on lodash. You could also probably use one of the smaller lodash modules since you only use throttle.
https://www.npmjs.com/package/lodash.throttle
In any case, thanks!
I usually need do distinguish if an element is below or above viewport.
For example:
I want to animate something when scrolling down to it.
But after I scrolled it out of viewport again (above it) or when I load page an element is above viewport I need to distinguish this state from the one when the element is below viewport.
Hi
I'm using this super simple code:
inView('.element')
.on('enter', console.log("in viewport"))
.on('exit', el => {
console.log("out viewport")
el.style.opacity = 0.5;
});
When I open the page the console prints immediatly "in viewport", though the .element is out of viewport. Scrolling down, when the .element appears, the console prints:
script.js:18654 Uncaught TypeError: this.handlers[t][n] is not a function
at t.value (http://localhost:3000/dist/js/script.js:18654:3035)
at http://localhost:3000/dist/js/script.js:18654:2676
at Array.forEach (native)
at t.value (http://localhost:3000/dist/js/script.js:18654:2552)
at http://localhost:3000/dist/js/script.js:18654:1018
at Array.forEach (native)
at http://localhost:3000/dist/js/script.js:18654:993
at r (http://localhost:3000/dist/js/script.js:18654:3843)
at b (http://localhost:3000/dist/js/script.js:18654:4367)
The library '/dist/in-view.min.js' is concatenated and minified with Gulp with other libraries in the 'dist/js/script.js' file.
This library seems really awesome, is there any way to get it working with angular 2?
I can't find a way to create multiple instances of InView.
'in-view.js' default export allows to get already created instance (see source). I also can't import InView variable as it's not exported (see source).
@gabrielflorit mentioned in issue #36 that he deals with the issue via creation of multiple InView objects, but I don't see any way to do this.
I'd suggest the variable exporting, because it seems to be the most non-destructive change.
Thank you.
Currently, in-view considers an element visible no matter how far into the viewport it is. (>0px) Per @WickyNilliams in #7, it'd be useful to be able to set a custom threshold for visibility. (0-1)
The API is up for discussion, but maybe something like this:
inView.set({
threshold: 0.5,
...
});
Or, to match the current offset method:
inView.threshold(0.5);
Hi all! I am basically using in-view to change section's bg color on scroll. It works flawlessly on every device but the iPhone 5/5s - on this device it just does not work at all. Any idea?
So package will be available for bower user too
We need to enforce some style guidelines, probably just the recommended eslint rules.
Hey there!
First of all - great tool! Very useful.
While playing with it, I've noticed that there is no common error handling. For example, I tried to register an event that do not exist (tried leave
instead of exit
).
Instead of a nice feedback about my error, I saw
Cannot read property 'push' of undefined
Which is not very helpful.
I suggest of adding few lines of checking if passed events/elements etc. are valid, and if not, instead of giving back an error, let's return some proper hint (for example: Unrecognized event name.
).
Have this error when compiled with Foundation 6 gulp (Zurb Stack) :
We need to expose the offset option. We could probably expose some other options as well. (triggers, threshold)
The registry class needs some love. It could be cleaned up a bit.
Hi, great module! thanks for your effort!
It would be great if we can also pass an element or array of elements to in-view... something like this:
inView(document.querySelectorAll('img')).on('enter', function(img) {
console.log(img.height);
});
what do you think?
I'd like to include this package into an isomorphic node application -- but currently the server rendering will fail when importing because of the addEventListener
and window
references. Ideally, a fallback would be in place to check if the window
type is undefined
.
in-view
works great for selectors already present in the DOM. But how can I detect elements entering/exiting that are created dynamically ?
It would be really nice to be able to set different threshold for enter and exit.
...some thing like:
const onEnter = () => {
inView.threshold(0.9);
inView('.item')
.on('enter', (el) => {
el.style.visibility = 'visible';
});
};
const onExit = () => {
inView.threshold(0.9);
inView('.item')
.on('exit', (el) => {
el.style.visibility = 'hidden';
});
};
If the script is loaded into the <head>
, the instantiation of MutationObserver, done on line 51 of in-view.js, should be done inside a DOMContentLoaded
event, to prevent the following error:
Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.
I'm very new to JS, so please excuse this (probably) dumb question.
What is the proper syntax for using .offset? I'm looking to make the color change about 500px after .album-section enters the view. Where would the .offset(500); go?
inView('.album-section').on('enter', function(el){
Thanks so much!
how can i pass argument with jquery selector and function?
somthing like:
$('*[data-animate]').inview(function () {});
I'm trying to write a unit-test for my module that's using in-view
library. However, I'm not sure how to get around the constructor to call on
method.
Here's my code
'use strict';
import inView from 'in-view';
module.exports = (options) => {
const selector = options.selector || '';
const onEnter = options.onEnter || function() {};
const arrayOfElements = [].slice.call(document.querySelectorAll(selector));
const theElement = arrayOfElements[0];
const dataSource = theElement.getAttribute('data-source') || '';
inView(selector).on('enter', () => onEnter(dataSource));
};
Here's my test
'use strict';
import jsdom from 'jsdom';
import helper from '../../helpers/setup';
import chai from 'chai';
const expect = chai.expect;
import sinon from 'sinon'
import * as inView from 'in-view';
import inViewPath from '../../../src/lib/inViewExists';
describe.only('In View Exists', () => {
let thePage;
let sandbox;
let module;
let callback;
before(() => {
thePage = helper(jsdom, 'index.html');
sandbox = sinon.sandbox.create();
});
after(() => {
thePage.cleanup();
sandbox.restore();
});
beforeEach(() => {
callback = sinon.spy();
});
it('should call enter', () => {
const config = {
selector: 'body',
onEnter: function (event) {console.log(event)}
};
// really not sure how to mock `in-view` and call `on` method so I can test the callback from `onEnter`
inViewPath(config);
});
});
In single page applications, there are cases we want the inview
functionality and some others we don't. It would be handy to be able to remove event listeners from page when we want to.
Copied from #11 (comment) :
Hi, thank you for the useful library.
I think, the
lodash
inpackage.json
should be moved todevDependencies
fromdependencies
.
Some package managers try to install the unneededlodash
when thein-view
is installed. We have to remove it every time.
All bundled libraries are typically added todevDependencies
.
Or, is there any reason to be in dependencies
?
Even if in-view is still in v0.x
, not having a changelog is kind of tricky when you update from v0.4.2
to v0.6.1
and there were any breaking changes in compatibility.
I get a Uncaught ReferenceError: el is not defined when I call it like this:
inView('.about video')
.on('enter', console.log(el) );
Due to restrictions I cannot use the ES6 arrow function. How can I fix this?
Nowadays there's a native IntersectionObserver
API pioneered by Chrome that is being rapidly adopted and moved through the standardization process. Moreover, there are API-compliant polyfills for it.
I imported the file in the dist folder on a jsbin and I get the following error in it:
in-view.min.js:6 Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.
This is my JS:
function loaded () {
inView('.foo')
.on('enter', el => {
console.log("it's here")
})
.on('exit', el => {
console.log("here")
});
}
and this is my HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://rawgit.com/camwiegert/in-view/master/dist/in-view.min.js"></script>
<title>JS Bin</title>
</head>
<body onload="loaded();">
<div></div>
<p class="foo">foo</p>
</body>
</html>
Any suggestions? Did I do something wrong?
Android 6, chrome browser. When zooming in the view, the library doesn't register horizontal scroll, as if the viewport is floated to left.
Hi, I was wondering if you stumble on in-viewport maybe https://github.com/vvo/in-viewport?
In any case I would be happy discussing the differences and maybe merging both projects somehow.
Your API is well done, I like the enter/exit part.
One thing that you are missing is watching the DOM for style/size changes. Watching scroll/size/load is not sufficient because you have also to take into account style modifications on nodes (all the DOM) for instance.
https://github.com/vvo/in-viewport was extracted from https://github.com/vvo/lazyload which is a battle tested production ready generic lazyloader used on many websites including very big ones.
I am all in in making the best out of both projects in a single one if you are interested in.
Is it possible to define the offset individual for each item?
Current its for all elements, or isn't?
I'm opening this issue to discuss the roadmap to a 1.0.0 release. What does the API look like? How can we maximize flexibility while minimizing API surface area and handling performance responsibly?
Here are my initial thoughts on API:
window
.offset
, threshold
, and test
individually, set all of them with this method and an options object..is
, accept an options object for custom checking, falling back to per-selector or global options.Most of the changes here are to the way we handle options. We'd default to global when per-selector settings aren't set, and add the ability to override both when manually checking with .is
or Registry.check
.
I'd also like to add a set of demos, stress tests, and a more comprehensive test suite.
Feedback appreciated!
Think the title explains my wish.
Right now I have done a quick fix that works for me, and that is to change export default inView()
to export default inView
so that we can create multiple instance of in-view. See README for usage, if people are interested.
e.g:
inView('.someSelector')
.offset(100)
.on('enter', doSomething)
.on('exit', el => {
el.style.opacity = 0.5;
});
By passing the passive: true option to the addEventListener call you can inform the browser that the callback won't preventDefault(). This has noticeable performance benefits -- see https://developers.google.com/web/updates/2016/06/passive-event-listeners
hi and thank you working on this little library :)
i could imagine that in-view would make a perfect scroll-spy library if I’d be able to customize the inViewport function. You’re already exporting the is
function as part of the libraries interface which gives me the opportunity to implement my own version and just overwrite your version.
unfortunately the registry imports the inViewport function from your module and does not take it as an argument. if you modify to use the is
function from the interface that should be everything that needs to be done to support this usecase.
thanks in advance
Hello,
What do you think about using rAF instead of using the scroll event.
https://gist.github.com/Warry/4254579
Cheers
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.