i'm using angularjs WITHOUT jquery, and trying to create scroll event listener.
tried this approach:
$rootScope.$watch(function() {
return $window.scrollY;
}, function(n,o) {
console.log('scroll');
});
but it dosen't work..
I managed to achieve this goal using this technique to create resize listener:
$rootScope.$watch(function() { // Listens to window size change
return $window.innerWidth;
}, function(n, o) {
console.log('resize');
});
is there a proper way to create pure angularjs scroll listener?
creating scroll event listener, 'The Angular Way', is actually very simple, using $window:
$window.onscroll = function() {
console.log('scroll');
};
try using onscroll event of javascript
Yes. your correct AngularJs provide $anchorScroll to scroll across the page but not that much effective. You can either go top or bottom like this. If you want scroll at particular position across vertical or horizontal $anchorScroll doesn't have that option. You have to go for normal javascript even for animation also. If you would like to explore more in Angular Scroll please have a look at this answer. Grate!!
Related
Listening for the domready event in normal js Google maps is relatively easy
as outlined here :
infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(infoWindow, 'domready', function() {
// whatever you want to do once the DOM is ready
});
However it doesn't seem obvious how to do it in angular-google-maps.
Is there a solution ?
The solution when using Angular Google Maps involves using the infowindow control object - see docs.
As noted in this issue - where I first posted this solution - you can create an empty infowindow control object within the main controller :
$scope.infowindowControl = {};
Then you scope bind your new object in the ui-gmap-window directive definition like :
<ui-gmap-window
options="windowOptions"
closeClick="closeClick()"
control="infowindowControl"
>
On infowindow open (actually unsure at what point) - it will pass five functions to the empty object you created within $scope. Some of these functions are noted in the documentation but in a rather haphazard and non-defined way :
getChildWindows()
getGWindows()
getPlurals()
hideWindow()
showWindow()
The one that you need is getGWindows() - which you put inside your marker click event.
This will get you an array of the open infowindows and you can now attach an event listener in the standard google maps fashion, like :
var windows = $scope.infowindowControl.getGWindows();
console.log('inside click after getGWindows ', windows);
google.maps.event.addListener(windows[0], 'domready', function() {
console.log('infowindow domready just fired !!');
});
While it's not an ideal, well documented or easy solution (and took me a number of hours to figure out) - and passing functions to an empty object is frankly counter-intuitive - it does seem to work.
Plunker here.
I am building a Cordova/PhoneGap app. I am using Iscroll5 (https://github.com/mtr/angular-iscroll) for building a crossplatform pull-to-refresh feature. Seeing this example http://www.kamrat.com/test/iScroll5/iscroll5-pull-test.html, i want something similar but without using probe, as scrolling seems jumpy with this on. Is there any event or a way to know when the user preforms a touchend? Something like a beforeScrollEnd? Or is there a way to bind touchend to iscroll-element?
I been struggling for days to create this feature to work nicely but without any luck.
Simply add the touchend event to the HTML element, not the IScroll object.
So, if you have created your IScroll using
var scroll = new IScroll("#content");
Then just add your event like this:
document.getElementById("content").addEventListener("touchend", function () {
// do your refresh
}, false);
I have a fixed top menu in Angular but when I try to switch page (within the app) the browser windows is not scrolling up.
I try to do this in my controller (this code is loaded every time i switch page within the app):
$('body').scroll();
window.scrollTo(0, 0);
$("html, body").animate({ scrollTop: 0 }, 100);
None of which is working.
Is there any trick that i am missing?
I tried this as well:
$location.hash('#top');
// call $anchorScroll()
$anchorScroll();
but without success
First of all, you should never attach DOM events or modify DOM from controller. You can use directives for that.
As per you question - AngularJS has an event called '$routeChangeSuccess'.
You can attach handler to this event with $scope.$on('$routeChangeSuccess', function () {...}) and run scrolling code inside.
I am having an odd, safari-only scrolling behavior using AngularJS.
Whenever the user flips between pages, the pages are being changed as if they are AJAX. I understand they are in AngualrJS, but the resulting behavior is that the browser does not scroll to top when the user switches pages.
I've tried to force the browser to scroll to top whenever a new controller is being used, but it does not seem to do anything.
I'm running the following JS at the top of every controller:
document.body.scrollTop = document.documentElement.scrollTop = 0;
This is also a Safari-only bug, every other browser will scroll to top when the page changes. Has anyone encountered a similar issue or think of a better way to resolve it?
$window.scrollTo(0,0) will scroll to the top of the page.
I just found a nice plugin (pure angularJS) that supports animations also:
https://github.com/durated/angular-scroll
you can use this:
.run(["$rootScope", "$window", '$location', function($rootScope, $window, $location) {
$rootScope.$on('$routeChangeStart', function(evt, absNewUrl, absOldUrl){
$window.scrollTo(0,0); //scroll to top of page after each route change
}}])
or for tab switches you can use the $window.scrollTo(0,0); in your controller
Have you tried using $anchorScroll()? it's documented here.
I got the same problem while using AngularJS in a Cordova App. In a normal Browser or on Android i have no trouble but on ios i get the same behavior as discribed by Neil.
The AngularJS documentation on $anchorScroll is not that great so i thought to post this link which helped me way more:
http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html
You can use $anchorScroll
$scope.gotoTop = function (){
// set the location.hash to the id of
// the element you wish to scroll to.
$location.hash('top');
// call $anchorScroll()
$anchorScroll();
};
Like #nonstopbutton said, adding autoscroll="true" to my ngView element worked for me too. I mention this here because it was a comment to an answer and it was not easy to see his reply.
More information here: https://stackoverflow.com/a/24549173/1578861
I'd a similar issue with Chrome. However, I don't know if any specific external library is causing this issue or otherwise.
However I wrote this piece of code at app level and it works.
$rootScope.$on('$viewContentLoaded', function(){
$window.scrollTo(0, 0);
});
Call $window.scrollTo(0,0); after locationChangeSuccess event:
$rootScope.$on("$locationChangeSuccess",
function(event, current, previous, rejection) {
$window.scrollTo(0,0);
});
In the controller you can actually drop the $ from window and simply putwindow.scrollTo(0,0); without having to inject $window into the controller. It worked great for me.
Is there a convenient way to add an effect when I leave a page (close a view/layout) and open a new one in the same region ? (something like a fade effect)
Marionette regions have a method called open that by default just replace the HTML of the old view with the new view. You can override this method to do any animation you like. From the region documentation:
Set How View's el Is Attached
If you need to change how the view is attached to the DOM when
showing a view via a region, override the open method of the
region. This method receives one parameter - the view to show.
The default implementation of open is:
Marionette.Region.prototype.open = function(view){
this.$el.html(view.el);
}
This will replace the contents of the region with the view's
el / content. You can change to this be anything you wish,
though, facilitating transition effects and more.
Marionette.Region.prototype.open = function(view){
this.$el.hide();
this.$el.html(view.el);
this.$el.slideDown("fast");
}
This example will cause a view to slide down from the top
of the region, instead of just appearing in place.
You could override the close function on the view, doing something like this:
close: function () {
// fancy fade-out effects
Backbone.Marionette.View.prototype.close.apply(this, arguments);
}
And do something similar with your render functions.
This seems to work for me:
this.views = {
messageItem: Marionette.ItemView.extend({
template: Handlebars.templates.messaging_item,
tagName: "li",
className: "messaging-item",
render: function(){
this.$el.html(this.template(this.model.attributes));
this.$el.hide();
},
onShow: function(){
this.$el.slideDown(800);
}
})
};
For future users people could user my plugin for Transition Support in marionette.
https://github.com/saqibshakil/Marionette.TransitionRegion/
I used css3 transitions as those have more hardware support than jquery animations. on the downside using this makes the code async so be carefull of that.
I think this could be useful for you.
The following marionette plugin that adds 4 kind of transitions. There can be easily added more transition types.
Basically instead of using yourRegion.show(view)...
you can use now yourRegion.showAnimated(view, {animationType: 'yourAnimation'});
it's very easy to use.
https://github.com/marcinkrysiak1979/marionette.showAnimated
see the documentation on github for more info