I am trying to create a sticky directive that makes the element on which it is present sticky while scrolling (like a sticky header). The way I intend to do this is by first cloning the DOM element/template the directive is present on and as you scroll up the clone sticks to the top using position: fixed, top: 0, width: blapx. The reason for using the clone is to ensure the viewport height doesn't change and there isn't a jump in the layout. Since the clone uses the position: fixed it needs to be an exact replica of the original element/DOM and preserve all of it's binding.

I have tried creating a directive called sticky that you could place on the element that you want to make sticky as you scroll. My initial idea was using this.viewRef.createEmbeddedView(templateRef inside the directive. But the directive only gets access to ViewContainerRef and ElementRef and NOT TemplateRef since it isn't a structural directive. I do not intend to use structural directive since we could only have one stuctural directive per element and this could be restrictive. For eg, I intend to use this sticky directive on the table header which is constructed using cdk-table and the header row uses <tr *cdkHeaderRowDef></tr> so I can't really use a structural directive here. Also, the cdk-table doesn't allow inserting any other tags/components except for table tags.

Also, I can't use the resolveFactory(component) inside the directive since the directive could be present on a simple DOM element such as as a div. For eg., <div class="header" sticky> contents here.. </div>

Also, I wouldn't like to use position: sticky as it doesn't have full cross-browser support.

Due to these restrictions I would like to make use of an attribute directive to meet all the requirements.

Example usage of my directive. Note, it could also be present on 2 or more elements in the view. In this case the second one sticks below the first one and so on.. This is just additional info and not really relates to the original problem.

<div class="header" sticky>
 Title of the page
 <button class="btn btn-default"> Save</button>
<tr cdk-header-row *cdkHeaderRowDef="selectedColumnIds" sticky>
<summary-element sticky>...some content</summar-element>

In the above sample I would like to clone the elements using the sticky directive present on each of them and also make sure - directive clones them when they are rendered in the view - the clone changes when the actual element changes.

Angular: 7.0.2

0 Answers