Change heights of elements dynamically - Angular 5 - javascript

I have 2 div elements that are connected, in the left one I have list of images, and in the right one I have details of each image. I open the right div on clicking on image, and it has absolute position, but then I get into a problem.
I need to calculate heights of those 2 divs, so I always have the same height - each time i click something, change something... (I can have only one image in the left div and it has a lot of information so the right div's height is bigger, or I can have 100 images on the left so left height is bigger). This is what I tried, but it doesn't work good enough:
leftHeight: number;
rightHeight: number;
ngDoCheck() {
if (window.innerWidth < 1336 && this.openDetails) {
this.chRef.detectChanges();
if (this.leftElement.nativeElement.clientHeight > this.rightElement.nativeElement.clientHeight) {
this.rightHeight = this.leftElement.nativeElement.clientHeight;
} else {
this.leftHeight = this.rightElement.nativeElement.clientHeight;
}
this.chRef.detectChanges();
}
}
HTML:
<div class="wrapper">
<div class="left-part" #leftElement [style.height.px]="leftHeight - 40">
<!-- some ngFor is here with images -->
</div>
<div [#focusPanel]='smallScreen' *ngIf="openDetails" #rightElement class="right-part" [style.height.px]="rightHeight - 65">
<!-- some details of each image -->
</div>
</div>
Any suggestion on what to try, what else to do?
EDIT: This semi-works, I set the height of elements at start, but it doesn't change the height after it, doesn't calculate again

I'm not sure this will help, but have you try to call to your function ngDoCheck in ngAfterViewChecked event?
It shoul'd be something similar to this:
export class YourComponent implements AfterViewChecked {
constructor(private cdRef:ChangeDetectorRef) {}
ngAfterViewChecked() {
this.ngDoCheck();
}

You can set scroll bars on right div. Simply add to css:
.scrollBarClass {
max-height: 500px;
overflow-y: scroll;
}
and then in your right div add:
<div class="scrollBarClass"> </div>
Edited answer:
If you have dinamicaly set height of both div's, then simply set
<div class="scrollBarClass"> </div>
on both divs, and you will have scroll if they become too large.

Related

How to force scroll in overflow-y div

I'm trying to force an offset scroll in a div that contain a ngfor list
I tried this on the div that as the overflow-y:
#ViewChild('list') listRef: ElementRef;
then on click I try this with some log to be sure it's called
this.listRef.nativeElement.offsetTop = 500;
Nothing happens, any idea how I can achieve this ?
EDIT :
Html :
<div
#gridContainerId
class="gridContainer">
<a *ngFor="let item of images;">
<img src="{{getImage(item)}}"/>
</a>
</div>
css :
.gridContainer {
height: 90vh;
overflow-y: scroll;
}
component :
#ViewChild('gridContainerId') ref: ElementRef;
this.store.pipe(
select(fromImages.getImages),
takeWhile(() => this.componentActive)
).subscribe(imagesItems => {
this.images = imagesItems;
updateScroll();
}
);
updateScroll(){
this.ref.nativeElement.scrollTop = this.ref.nativeElement.scrollHeight;
}
I've been recently in your same scenario, when click certain button, the div scrolled to bottom, i achieved it with this code:
this.messagesContainer.nativeElement.scrollTop = this.messagesContainer.nativeElement.scrollHeight;
the property scrollTop is to specify the number of pixels to be scrolled from the top of the view.
and the property scrollHeight is to get the total height of the div.

Removing display: none when changing between #media sizes

I have two divs. When the resolution is large enough, both divs are shown next to each other. But when the resolution is too small it only shows one of the divs, but I can toggle between them with two buttons appearing at this resolution.
So my HTML is just like this:
<div id="buttons">
<p>LEFT</p>
<p>RIGHT</p>
</div>
<div id="left"> CONTENT </div>
<div id="right"> CONTENT </div>
The JavaScript used for the toggle is just:
<script>
$(function() {
$('#buttons> p').click(function() {
var ix = $(this).index();
$('#left').toggle( ix === 0 );
$('#right').toggle( ix === 1 );
});
});
</script>
Basically everything works fine. When the resolution is too small, the buttons pop up, and it is divided into one div at a time, and when the resolution is large enough they are next to each other.
However, if I change the width of my browser window, and toggle between the two divs, and then go back, one of the divs still has display: none resulting in it not showing when there has been toggled.
I know one might argue that people don't change resolutions on phones, and therefore this shouldn't be a problem. But somehow it annoys me a lot. So I was wondering if there was some way to tell it, that if above a certain resolution, BOTH divs should have the display: none or inline style removed.
You could add a resize listener to show both elements if the size is sufficiently high:
$('#buttons> p').click(function() {
var ix = $(this).index();
$('#left').toggle(ix === 0);
$('#right').toggle(ix === 1);
});
$(window).resize(function() {
if (Number($(window).width()) > 600) $('#left, #right').show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="buttons">
<p>LEFT</p>
<p>RIGHT</p>
</div>
<div id="left"> CONTENT1 </div>
<div id="right"> CONTENT2 </div>
use media queries for setting different css based on screen size. PFb sample. you can also add display style as css as None or Block based on screen width.
body {
background-color: red;
}
#media only screen and (max-width: 600px) {
body {
background-color: lightblue;
}
}

Making a certain id disapear once I scroll within a specific section?

Trying to make a specific id (#logo) disapear once I scroll in specific section id ("#performance-graphs"), the id that is hidden must show itself again once I have scrolled out that section.
Please see my code below, currently id does not work but the idea is there, not sure what I am doing wrong. basically I trying to make my main header smaller by removing the logo when it gets to the chart section.
JQUERY CODE
<script type="text/javascript">
$(document).ready(function() {
$('#performance-charts').scroll(function() {
var scroll = $('#performance-charts').scrollTop();
if (scroll > 10) {
$('#logo').css("display", "hidden").fadeOut(250);
}
else {
$('#logo').css("display", "block").fadeIn(250);
}
});
});
</script>
HTML SNIPPET BODY
<section id="performance-graphs">
<a id="performance-graphs"></a>
<div class="double-space"></div>
<div class="centered-wrapper">
<h1 class="section-title">charting performance</h1>
...............................................................
</div>
</section>
HTML SNIPPET HEADER
<span itemscope itemtype="http://schema.org/LocalBusiness"><header id="fixed" class="solid-header">
<div class="centered-wrapper">
<div itemscope itemtype="http://schema.org/Service"><div itemprop="ServiceType" content="Asset and Fund Management"></div></div>
<div id="logo"><img src="../images/value_images/VPM_global3a.png" alt="White Fleet Globel Select Opportunities">
<p>LU0721514452:USD - Managed by Value Portfolio Managers (Pty) Ltd</p></div>
<br>
<a class="nav-btn"><i class="fa fa-bars"></i><span>Menu</span></a>BaB
Your help would be greatly appreciated.
Ok here you go. I used your fiddle and updatet it HERE
Basically you have bad code there, because an id should be unique! (i just added another charakter to one of the duplicated IDs.
I just updated your JS Code like this:
if ($(document).scrollTop() > $('section#performance-graphss').offset().top) {
Because you need the offset().top of your graph container and compare it to the scroll position of the qhole document.
EDIT:
Does this FIDDLE help?
I just added another check for hiding the element:
$('section#performance-graphss').offset().top + $('section#performance-graphss').height() > $(document).scrollTop()
So when you scroll past the container the logo gets display: blick; again.
Watch out for the CSS i added: The containers need a height.
#performance-graphss {
width: 100%;
height: 700px;
display: block;
}

One page website change menu color each section

I'm currently building a one page website with a fixed navigation menu (with a blue background). This one page website has 4 sections, 2 with a blue background and 2 with a white background.
My idea to do with this menu is when i scroll (not mouse hover) over a blue section, the menu background turns white. and when i scroll over a white section, the background changes back to blue.
An example can be found here.
(Not my site, but look at the changing color of the menu while scrolling)
My HTML code looks like this:
<div class="subMenu" >
<div class="inner">
Home
Over mij
Kennis
Projecten
Contact
</div>
</div>
<div class="section s1">
<div class="inner">
<h1>Section 1</h1>
</div>
</div>
<div class="section s2">
<div class="inner">
<h1>Section 2</h1>
</div>
</div>
<div class="section s3">
<div class="inner">
<h1>Section 3</h1>
</div>
</div>
<div class="section s4">
<div class="inner">
<h1>Section 4</h1>
</div>
</div>
Is there a simple way to do this?
Thanks in advance.
I've found/created a temporary fix for my problem.
$(window).scroll(function(e) {
var s1 = $('.s1'),
s2 = $('.s2'),
s3 = $('.s3'),
s4 = $('.s4'),
menu = $('.menu'),
diff = s1[0].offsetTop - window.pageYOffset;
diff2 = s2[0].offsetTop - window.pageYOffset;
diff3 = s3[0].offsetTop - window.pageYOffset;
diff4 = s4[0].offsetTop - window.pageYOffset;
if(diff < 100) {
$(".menu").addClass("white");
$(".menu").removeClass("blue");
}
if(diff2 < 100) {
$(".menu").addClass("blue");
$(".menu").removeClass("white");
}
if(diff3 < 100) {
$(".menu").addClass("white");
$(".menu").removeClass("blue");
}
if(diff4 < 100) {
$(".menu").addClass("blue");
$(".menu").removeClass("white");
}
if(diff > 100) {
$(".menu").removeClass("white");
$(".menu").removeClass("blue");
}
});
JSFIDDLE DEMO
Not sure exactly what you want to do but, unless you want to change the background of another element (other than the one you're mousing over) an easy way is to use the :hover css selector.
like this:
.inner:hover{
background-color: blue;
}
this will make changes to the class when you're hovering over.
If however, you want to make changes to a different element, then you need to attach an event handler through javscript:
(rough code, not tested)
var menuitem = document.getElementById('menu_to_turn_other_stuff_blue'); // can use getElementsByTagName here, but you'll have to walk the HTMLCollection returned
var otheritem = document.getElementById('other_stuff_to_turn_blue');
menuitem.onmouseover = function(){ otheritem.style.backgroundColor = "blue"; } // ideally, you want to use addEventListener, not directly modifying the attribute this way, but either will work - addEventListener is however the recommended way
you can use onmouseout or the proper event handler through addEventListener to change the color back if necessary. The CSS solution will work automatically for this.
Take a look at the source of the example website you gave: view-source:http://www.franzsans.de/
section id="info" class="bg-white b-blue f-grey"
Just as quick example with jQuery a Fiddle
$(".s1,.s2").hover(function ()
{
$(".subMenu").removeClass("white").addClass("blue");
});
$(".s3,.s4").hover(function ()
{
$(".subMenu").removeClass("blue").addClass("white");
});
$(".s1,.s2,.s3,.s4").mouseleave(function ()
{
$(".subMenu").removeClass("blue").removeClass("white");
});
Example CSS:
body {
background-color:yellow;
}
.subMenu a {
color:black;
}
.s3, .s4, .white {
background-color:white;
}
.s1, .s2, .blue {
background-color:blue;
}
For reference: http://api.jquery.com/addclass/, http://api.jquery.com/removeClass/, http://api.jquery.com/hover/, http://api.jquery.com/mouseleave/
Update for updated question: Previously question was to change background-color of menu in case scrolling over section which was misunderstood as hover. As question was clarified, approach would be e.g. to add jquery inview and to change the background-color when the white or blue section is in view following the instructions provided on given link (as I don't want to just copy them from there and final steps could be done by OP).
Just as example for using inview new Fiddle with inview. No need to style it, just expand the result window above the 1st section and scroll down; you'll notice that color will change according to the section which is in view. Added following for that: the mentioned inview.js and
$('.s1,.s2').bind('inview', changeBlue);
$('.s3,.s4').bind('inview', changeWhite);
where the changeBlue() and changeWhite() functions are just the hover-events from above.

How to Slide or Move this Set of Divs

I have a set of seven div's with the following properties:
height: 100px;
width: 100px;
display: inline-block;
I have a wrapper div containing these seven blocks with only enough room to fit four and change.
The overflow is hidden.
How can I make this function so that when you clicked and dragged horizontally, or swiped with your finger on mobile, the entire row of div blocks would slide to show the previously hidden ones?
Please refer to this jsFiddle for the example.
We can use css or jQuery here.
*Bonus, show fractions of otherwise entirely hidden div's at the edges of the container.
Based on jfriend00's answer I modified this so it will work on touch/click and move with the mouse.
var last_x = null;
var holding = false;
//Mark the wrapper as clicked/touched
$('.wrapper').mousedown(function(){
holding=true;
});
//We do this on document so that even if movement goes outside of the container the event will fire
$(document).mouseup(function(){
holding=false;
});
$('.wrapper').mousemove(function(e){
if(last_x === null || !holding) //If this is the first movement
{
last_x = e.pageX;
return;
}
var ammount = e.pageX - last_x;
$('.slider',this).css('margin-left', '+=' + ammount);
last_x = e.pageX;
});
The gist of how this works is that when the mousedown event is detected on the container the script starts tracking all mouse movement and moves the content with the mouse. When the mouse is released it stop tracking movement.
Fiddle: http://jsfiddle.net/NvJam/2/
Since no one has mentioned jQuery.Kinetic I'll add this:
<div class="carousel">
<div class="wrapper">
<div class="first">First</div>
<div class="second">Second</div>
<div class="third">Third</div>
<div class="fourth">Fourth</div>
<div class="fifth">Fifth</div>
<div class="sixth">Sixth</div>
<div class="seventh">Seventh</div>
</div>
</div>
$('.carousel').kinetic();
Demo: http://jsfiddle.net/louisbros/2pRBg/6/
see here
.wrapper {
width: 900px;
height: 100px;
overflow: hidden;
}
You can put an additional container div and use absolute positioning on that div to move the items left/right. Here's a demo:
http://jsfiddle.net/jfriend00/7edc9/
HTML looks like this:
<div class="wrapper">
<div class="slider">
<div class="first">First</div>
<div class="second">Second</div>
<div class="third">Third</div>
<div class="fourth">Fourth</div>
<div class="fifth">Fifth</div>
<div class="sixth">Sixth</div>
<div class="seventh">Seventh</div>
</div>
</div>
You weren't entirely clear how you wanted to move them on non-touch screens, but here's some event handlers that work on buttons:
$("#left").click(function() {
$(".slider").stop(true, true).animate({left: "-=125px"}, 500);
});
$("#right").click(function() {
$(".slider").stop(true, true).animate({left: "+=125px"}, 500);
});
Something similar could be hooked up for touch events.
Even better solution: use the JQuery UI draggable:
$('.slider').draggable({
axis: 'x',
});
http://jsfiddle.net/DCuGV/2/

Categories