Detecting page scroll/ current section being viewed in AngularJs - angularjs

My page is divided into sections : #page-1 and #page-2
See Plnkr: http://plnkr.co/edit/RZJLmsWDfs63dC0QuDJi
<body>
<section id="page-1">
This is page 1. It takes the whole height of the browser. User has to scroll down to see page-2.
</section>
<section id="page-2">
<span class="animated bounce">This is page 2 </span>
</section>
</body>
Animation classes are being applied to different elements in #page-2.
However by the time the user scrolls down to these elements, the animation has already finished. Hence they just look like static objects.
Is there anyway I can detect when #page-2 is currently being viewed and then call a function to addClass('animated bounce') to certain elements ?
I would like to achieve this in angularjs if possible

I have found a angularjs directive that is probably helpfull for you in this case. Inview tries to solve this exact problem by reporting to you if a dom element is visible on the screen. Unfortunately I have been unable to test my solution because I couldn't find a minified js file of Inview but I assembled some code that should work:
<section id="page-2" in-view="{$inview ? isFocused=true;}">
<div ng-class="{'animated bounce': isFocused}">This is page 2 </div>
</section>
The $inview is supposed to be true whenever the element is in visible in the browser. This leads to the scope variable isFocused being set to true and therefor the animation class is added to your div.
This should work as you have intended in your question, if it does not work for some reason please let me know so I can improve my answer.

Related

Issue selecting CSS Selector for Google Tag Manager

I am new to GTM and am creating a trigger on a site for my company. I have tried all the ways I know how and looked at Simo Ahava's blog and cannot get my trigger to fire. I am making a trigger that fires on element click and wants to have the Click Element match the CSS selector but cannot get it to work properly.
This is what I see when I inspect the component on the page:
<div _ngcontent-my-app-c1="" class="page-complementary jss-page-complementary" id="jss-page-complementary" name="jss-page-complementary" sc-placeholder="">
<!---->
<!---->
<app-tab-stories _nghost-my-app-c26="" _ngcontent-my-app-c1="" class="ng-star-inserted">
<!---->
<div _ngcontent-my-app-c26="" id="our-stories" class="tab-stories tab-stories--option-three">
<div _ngcontent-my-app-c26="" class="tab-stories__inner">
<div _ngcontent-my-app-c26="" class="tab-stories__header">
<h2 _ngcontent-my-app-c26="" class="tab-stories__heading">Our Stories</h2></div><div _ngcontent-my-app-c26="" class="tab-stories__wrapper">
<mat-tab-group _ngcontent-my-app-c26="" class="tab-stories__tabs mat-tab-group mat-primary ng-animate-disabled mat-tab-group-dynamic-height" disableripple="" dynamicheight="">
<img _ngcontent-my-app-c9="" class="ng-tns-c9-25 tab-stories__image ng-trigger ng-trigger-fadeIn ng-star-inserted" id="app-deferred-image_id_d1e0186a-6714-c0b4-649e-b9234689c136" alt="null" src="/-/media/images/images-sc9/locations/pch/general-pch/patient-stories/lexie-gardiner-square.ashx?&mw=400" style="">
I have tried the following CSS Selectors with no success, any help would be appreciated. The goal is to track that whenever anyone clicks on one of the stories under "Our Stories" they do not link off to anywhere just hidden content.
.tab-stories
.tab-stories__wraper
.tab-stories__image
div#our-stories
.tab-stories*
div#tab-stories*
div#tab-stories
Try .tab-stories__tabs
If it doesn't work, edit your question and add a complete set of html with closing tags so that we could actually inject it into a page and see how it looks.
You don't need to try your selectors in GTM every time. That takes too long.
Just do the following:
Inspect your element to open the Elements tab in the Chrome Debugger.
press ctrl+f while the Elements tab is being focused and start typing your CSS selectors.
The search in the Elements tab is smart enough to not only match literal matches, but CSS selectors matches too.
Debugging your selectors through the Elements tab is the best way to make sure nothing else would trigger your rule on this page and to see what exactly will trigger it.

Best approach to change background image in AngularJs at runtime

I want to create generic feature that allows me to change background image of any section. After going through options provided I found these two approaches. Want to choose best approach to change image because on single page I want multiple times change background facility. It will be available to four to five sections.
Approach
Using Directive check this stack overflow link.
Also there is another approach of angular scope variables that we can updates at runtime.
<div ng-style="{'background-image': 'url(/images/' + backgroundImageUrl + ')'}"></div>
Required Usage ( With respect of Directive )
<body>
<section backgroundImage url="{{backgroundImageUrl1}}">
...
</section>
<section backgroundImage url="{{backgroundImageUrl2}}">
...
</section>
<section backgroundImage url="{{backgroundImageUrl3}}">
...
</section>
<section backgroundImage url="{{backgroundImageUrl4}}">
...
</section>
</body>
As shown above I am going to update background-image attribute for each section. If these property is set inside CSS file, it will reduce time to load images i.e. If we directly add inline css styling in HTML, all images will loaded on DOM load. It will make extra request to server to get images and load them in DOM. I wanted to follow strategy that will reduce loading time in my SPA(Single Page Application).
I think going with <div ng-style="{'background-image': 'url(/images/' + backgroundImageUrl + ')'}"></div> should be more effective.
You dont introduce another layer of complexity, directives create scopes, which are watched and digested, also directives must be compiled in the begining.
Using symple ng-style together with some specific url from controllers property shoudl only do request for that particular active image. Because of that i think it should be the optimal solution.

Loader/spinner animantion while route is changing

How can I show a spinner or loader gif animation while route is changing from one to another.
I am using ng view like as follows:
<div ng-view class="view-animate">
</div>
I am loading templates from server and also inline. While the HTTP request is pending I need to show the spinner/loader... any snippets?
You can show and hide the loader when location change starts and is completed, respectively.
Here is a plunkr that I have created for this situation. This uses ui-router and is taken from one of the apps that I have created, so it may not be useful as-is, but it will give you an idea on how to approach the problem.
HTML Code inserted below just to keep SO happy...
<ui-view class="view"></ui-view>
<div loader="" class="ng-hide"></div>
I hope it helps.
Abhi.

AngularJS using ng-if vs ng-show

In my AngularJS I have the following code where I check if there is a currently logged in user or not in order to switch the top app menu text from Login to Logout (login if no user is logged in) and vice versa. When I used ng-show ng-hide the app started to be extremely heavy so I tried switching to ng-if, but then the css effects on the top menu started not to work specifically in the login/ logout tab. So can someone please tell me what is the best approach to handle this situation with example please? Thanks
index.html
<div ng-controller="MenuController">
<li>
<div ng-if="userLevel() == 1">
Login
</div>
<div ng-if="userLevel() == 2">
Logout
</div>
</li>
</ul>
</div>
Controller:
controller('MenuController',
function MenuController($scope, UService){
$scope.userLevel = function(){
var userType = UService.checkULevel(); //This will return either 1, 2,3,4...etc
return userType;
};
});
The difference between ng-show and ng-if is that ng-show applies a display: none to the element when the specified expression is a false value, while the ng-if removes the node from the DOM, basically equivalent to the .empty in jQuery.
An approach you can consider for your element, is rather than using it within a controller, use a directive for the access level, and follow the approach described in this article, which is really flexible and allows you to have different elements in the UI depending on the user level: http://frederiknakstad.com/2013/01/21/authentication-in-single-page-applications-with-angular-js/
Another reason for your application to be slow when you check the user level, could be that every time that is evaluated your application has to perform a check on the server side, slowing the application. An approach for it would be to cache the result of that query, and then use it while the login status doesnt change. At that stage you can invalidate the cache and fetch the user level again, ready to update the UI.
The ng-if directive removes the content from the page and ng-show/ng-hide uses the CSS display property to hide content.
I am pretty sure that no-show is lighter than ng-if and no-show should not make the app too heavy. If it is becoming heavy, I think there could be other causes for it.
If you use ng-if the node is rendered only when the condition is true
In case of ng-show ng-hide the Nodes will be rendered but shown/hidden based on the condition if condition changes the same nodes are shown/hidden
when ever you use ng-if it will render only that code which satisfy the condition.
while ng-show ng-hide will render the code on page but will be hidden with the help of CSS properties.
so better to use ng-if for reducing the line of code to be rendered on page.

angular js reloading view

I'm using Angular JS and Angular IU-Router in my project and using a lot of ui-views. I have a situation where I need to change the language of the site, therefore I need to swap my ui-view's model to another model with the relevant language. I already have a service that detects the relevant model and passes it into the ui-view's controller. So if I can reload the ui-view, then in theory my problem would be solved.
I recall reading something about automatically reloading a ui-view (or possibly an ng-view) and re-instantiating its controller, but after much searching I haven't been able to find that information again.
Does anyone know what it is I'm looking for?
1 Take a look at angular-translate
https://github.com/PascalPrecht/angular-translate
2 In your case, add some if-else control ( ng-if, ng-switch etc. ) in the outer div, use the same subview in the inner div. Then change the settings.currentLang when the language changes may cause the subview reload (not tested).
<div ng-controller="containerCtrl">
<div ng-if="settings.currentLang=='en'">
<div ui-view='subview'></div>
</div>
<div ng-if="settings.currentLang=='ja'">
<div ui-view='subview'></div>
</div>
</div>

Resources