I want to create a function for for my header when its changing his size.
I have a logo img inside the header.I want when i change the headers height to be for example 80px the image to be 80 px as well.
I initialized a function in Javascript but doesnt work( i`m a beginner at Javascript). Please tell me what i m doing wrong in js and maybe show me the right way to do it.
<header class="header">
<div class="container">
<div class="header-content">
<img src='http://www.lazarangelov.com/wp-content/uploads/2015/12/logo1.jpg' class="logo" alt="logo">
<div class="menu-links">
<ul class="links-list">
<li>Home</li>
<li>Bio</li>
<li>Training</li>
<li>Academy</li>
<li>Gallery</li>
<li>Store</li>
<li>Contacts</li>
</ul>
</div>
</div>
</div>
</header>
.header {
background: blue;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 20;
height: 80px;}
.header-content{
display:flex;
}
.menu-links{
display:flex;
}
.links-list{
display:flex;
color:white;
}
const mainNav = document.querySelector('.header');
const img = document.querySelector('.logo');
if (mainNav.style.height == '80px') {
img.style.height = '80px';
} else {
img.style.height = '100px';
}
The .style property can only return style information that has been set directly into the HTML element, either statically in the HTML as in: <p style="something here"> or via the .style being set in JavaScript as in: element.style = something;. Your code is based on an if condition that checks mainNav.style.height, but the style property hasn't been set in HTML or JavaScript at that point.
Instead, use .getComputedStyle(), which returns the final value for the provided style after all computations (regardless of where they were applied) are taken into account.
I've added a red border to your image in the code below to show that it is expanding the height to be the same size as the header.
const mainNav = document.querySelector('.header');
const img = document.querySelector('.logo');
// You can't check the .style property if the element
// hasn't had that attribute or property set yet.
if (getComputedStyle(mainNav).height == '80px') {
img.style.height = '80px';
} else {
img.style.height = '100px';
}
.logo { border:1px dashed red; }
.header {
background: blue;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 20;
height: 80px;}
.header-content{
display:flex;
}
.menu-links{
display:flex;
}
.links-list {
display:flex;
color:white;
}
.links-list a { color: white; }
<header class="header">
<div class="container">
<div class="header-content">
<img src=
'http://www.lazarangelov.com/wp-content/uploads/2015/12/logo1.jpg'
class="logo" alt="logo">
<div class="menu-links">
<ul class="links-list">
<li>Home</li>
<li>Bio</li>
<li>Training</li>
<li>Academy</li>
<li>Gallery</li>
<li>Store</li>
<li>Contacts</li>
</ul>
</div>
</div>
</div>
</header>
The style property in Javascript only gives you the element's inline styles - those defined directly in a style attribute on it.
You need getComputedStyle to access the actual properties used, taking into account all CSS rules.
Related
I have a javascript project that I'm trying to convert into Angular and I'm having trouble understanding why the classes some of my are making the menu disappear even after reading the documentation again. I want the menu I have to rotate into and X only if .menu-btn is clicked on.
Here is the javascript code I'm trying to convert:
// Select DOM Items
const menuBtn = document.querySelector(".menu-btn");
const menu = document.querySelector(".menu");
const menuNav = document.querySelector(".menu-nav");
const menuBranding = document.querySelector(".menu-branding");
const navItems = document.querySelectorAll(".nav-item");
// Set Initial State Of Menu
let showMenu = false;
menuBtn.addEventListener("click", toggleMenu);
function toggleMenu() {
if (!showMenu) {
menuBtn.classList.add("close");
menu.classList.add("show");
menuNav.classList.add("show");
menuBranding.classList.add("show");
navItems.forEach((item) => item.classList.add("show"));
// Set Menu State
showMenu = true;
} else {
menuBtn.classList.remove("close");
menu.classList.remove("show");
menuNav.classList.remove("show");
menuBranding.classList.remove("show");
navItems.forEach((item) => item.classList.remove("show"));
// Set Menu State
showMenu = false;
}
}
app.component.html
<header>
<div class="container">
<div class="menu-btn" [class.menu-btn.close]="check" (click)="myfunction()">
<div class="btn-line"></div>
<div class="btn-line"></div>
<div class="btn-line"></div>
</div>
<!-- Overlay that comes up when you click menu -->
<!-- Profile Image put in through CSS -->
<nav class="menu" [class.menu-btn.show]="check" (click)="myfunction()">
<div class="menu-branding" [class.menu-btn.show]="check" (click)="myfunction()">
<div class="portrait"></div>
</div>
<!-- Pages -->
<ul class="menu-nav" [class.menu-btn.show]="check" (click)="myfunction()">
<li class="nav-item current" [class.menu-btn.show]="check" (click)="myfunction()">
Home
</li>
<li class="nav-item" [class.menu-btn.show]="check" (click)="myfunction()">
About
</li>
<li class="nav-item" [class.menu-btn.show]="check" (click)="myfunction()">
Work
</li>
<li class="nav-item" [class.menu-btn.show]="check" (click)="myfunction()">
Contact
</li>
</ul>
</nav>
</div>
</header>
app.component.scss
$primary-color: red;
$secondary-color: blue;
#mixin easeOut {
transition: all 0.5s ease-out;
}
.container{
background-color: grey;
height:100px;
box-sizing: border-box;
}
a{
text-decoration: none;
color:white;
}
.btn-line{
color:blue;
}
header{
position: fixed;
z-index:2;
width:100%;
}
.menu-btn{
position: absolute;
z-index:3;
right:35px;
top:35px;
cursor: pointer;
#include easeOut;
.btn-line{
width: 28px;
height: 3px;
margin: 0 0 5px 0;
background: white;
#include easeOut;
}
//Rotate Into X with Menu Lines
&.close {
transform: rotate(180deg);
.btn-line {
// Line 1 - Rotate
&:nth-child(1) {
transform: rotate(45deg) translate(5px, 5px);
}
// Line 2 - Hide
&:nth-child(2) {
opacity: 0;
}
// Line 3 - Rotate
&:nth-child(3) {
transform: rotate(-45deg) translate(7px, -6px);
}
}
}
}
.btn-line{
color:black;
}
app.component.ts
export class AppComponent {
title = 'menu';
check:boolean=true;
myfunction(){
this.check=true;
}
}
I believe the simple answer is that you cannot add two classes at once with the [class.xxx.yyy] directive...
If you want both classes applied you have to do it in two separate [class...] directives, or use an ngClass directive, e.g. [ngClass]="{ xxx: check, yyy: check }"
EDIT (following comment) your template has stuff such as [class.menu-btn.show]="check" I must have guessed wrong when I assumed that you wanted to add both the show and the menu-btn class based on the value of the variable check - if that wasn't your intention, I'm sorry. But at any rate, the class you wish to add must be the sole name in that directive (after class.), so if you want to add the show class, do [class.show]="check". And you can use multiple such directives, each for a different class.
I have a relative parent element that has multiple absolute child elements which wraps and adds rows of the images inside at bottom when the screen gets smaller. I wanted to achieve a height that resizes according to the height of its child element. However, my jquery code keeps adding the value on top of each other when resizing resulting in a large number. How can I achieve a height that changes when the window resizes and just get the last value.
Tried logging it on the console. Seems to work fine. However, what I wanted is just to get the last value and assign it as height when the window resizes.
http://evertaste-lislam.ga/ <--- This is the website im working with. Its the image gallery in the homepage.
$(window).resize(function () {
var pgContHeight = $('.pg-container').height();
var windowWidth = $(window).width();
if (windowWidth >= 992) {
pgContHeight *= 2; //<--Number of rows multiplied by height of image//
} else if (windowWidth <= 991 && windowWidth >= 768) {
pgContHeight *= 3;
} else if (windowWidth <= 767 && windowWidth >= 601) {
pgContHeight *= 4;
} else if (windowWidth <= 600) {
pgContHeight *= 8;
}
$('.photo-gallery-container').css('height', +pgContHeight + 'px');
})
$(window).trigger('resize');
})
.photo-gallery-container {
position: relative;
margin-top: 100px;
}
.photo-gallery-row-1 {
display: flex;
flex-flow: wrap;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.pg-container {
width: 25%; //**Width changes via media queries**//
position: relative;
}
.pg-container img {
max-width: 100%;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="photo-gallery-container">
<div class="photo-gallery-row-1"> <!-- I have 3 of these positioned absolute -->
<div class="pg-container">
<div class="overlay"></div>
<img src='//via.placeholder.com/350x150'>
</div>
<div class="pg-container">
<div class="overlay"></div>
<img src='//via.placeholder.com/350x150'>
</div>
<div class="pg-container">
<div class="overlay"></div>
<img src='//via.placeholder.com/350x150'>
</div>
<div class="pg-container">
<div class="overlay"></div>
<img src=//via.placeholder.com/350x150>
</div>
<div class="pg-container">
<div class="overlay"></div>
<img src='//via.placeholder.com/350x150'>
</div>
</div>
</div>
I'm not sure of what you are trying to accomplish. Is that a responsive images' gallery? If so, you don't necessarily have to use javascript to reach your goal. Do you know the padding bottom tricks? It allows you to define a width and then a height (via the padding bottom) with a ratio to that width (for exemple, you want square images, you need a 1/1 ratio like if your width is 25%, then your padding bottom will be 25%) etc...
I don't necesseraly find the usefullness of javascript here but maybe your absolute positionning is important so I'll wait for some clarification from you. Hope I helped!
.photo-gallery-container {
position: relative;
margin-top:100px;
}
.photo-gallery-row-1{
display: flex;
flex-flow:wrap;
top:0;
bottom:0;
left:0;
right:0;
margin: -1%;
}
.pg-container {
margin: 1%;
width: 23%;
height: 0;
padding-bottom: 25%;
position: relative;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
background-image: url('//via.placeholder.com/350x150');
}
#media screen and (max-width:40rem) {
.pg-container {
width: 31%;
padding-bottom: 31%;
}
}
/*Etc....*/
<div class="photo-gallery-container">
<div class="photo-gallery-row-1">
<div class="pg-container">
<div class="overlay"></div>
</div>
<div class="pg-container">
<div class="overlay"></div>
</div>
<div class="pg-container">
<div class="overlay"></div>
</div>
<div class="pg-container">
<div class="overlay"></div>
</div>
<div class="pg-container">
<div class="overlay"></div>
</div>
</div>
</div>
This question got complicated because of the idea behind how the approach was and how it should work in JS. I found out that i can simply use data-filter and just eliminate the idea of using absolute positioning when creating image galleries or portfolio galleries like this.
I'm pretty sure there is already an example for this but I couldn't find one, and I don't know exactly what to search for.
http://imgur.com/a/hHNkZ
I am trying to make a resizable div from the button circled in red above.
The photo behind this div comes from a slick slider ( http://kenwheeler.github.io/slick/ ).
<div class="slider-for">
<img src="images/product0.jpg" alt="">
<img src="images/product1.jpg" alt="">
<img src="images/product2.jpg" alt="">
<img src="images/product3.jpg" alt="">
</div>
I was thinking of making a width 0 div above, and then with the slider, increase its width with js maybe.
In this div, I want to put a recipe for that certain product. I have 4 photos, so the content has to change depending on picture. ( so it's not static content).
Does this need to be made in php?
I think this would be helpful to you:
https://jsfiddle.net/u0Ljnttg/1/
Its little bit complicated, but still good enough. :)
Just for sake of SO:
JS:
var links = document.getElementById("imageLinks");
links.onmousedown = function(e) {
var theSrc = e.target.dataset.src;
if (theSrc) {
str = "url(\"" + theSrc + "\");";
//Sorry for using this:
document.getElementById("imageBack").setAttribute("style", "background-image:" + str)
}
}
var resizer = document.getElementById("content-resize");
resizer.onmousedown = resizableStart;
function resizableStart(e) {
var elem = document.getElementById("content");
elem.originalW = elem.clientWidth;
this.onmousemove = resizableCheck;
this.onmouseup = this.onmouseout = resizableEnd;
}
function resizableCheck(e) {
var elem = document.getElementById("content");
if (elem.clientWidth === elem.originalW) {
elem.originalX = e.clientX;
this.onmousemove = resizableMove;
}
}
function resizableMove(e) {
var elem = document.getElementById("content");
var newW = elem.originalW - e.clientX + elem.originalX;
if (newW < elem.originalW) {
elem.style.width = newW + 'px';
}
}
function resizableEnd() {
this.onmousemove = this.onmouseout = this.onmouseup = null;
}
HTML:
<div class='container'>
<div class='images' id="imageBack" style="background-image: url('http://data.whicdn.com/images/20948152/large.png')">
<div class='content' id="content">
<div id="imageLinks">
<a href="#" data-src='http://ichef.bbci.co.uk/news/660/cpsprodpb/1325A/production/_88762487_junk_food.jpg'>1</a>
<a href="#" data-src='http://i.imgur.com/NhDejjN.jpg'>2</a>
<a href="#" data-src='https://s-media-cache-ak0.pinimg.com/564x/80/40/9d/80409d8c06d21e0c0416a40c2176def3.jpg'>3</a>
<a href="#" data-src='http://data.whicdn.com/images/20948152/large.png'>4</a>
</div>
<span id="content-resize"></span>
</div>
</div>
</div>
CSS:
html,
body {
min-height: 100% !important;
height: 100%;
}
.container {
width: 100%;
min-height: 100%;
height: 100%;
}
.images {
width: 100%;
min-height: 100% !important;
height: 100%;
}
#content {
min-height: 100% !important;
height: 100%;
/*Change this to change width*/
width: 70%;
resize: horizontal;
float: right;
position: relative;
background: white;
}
div {
border: 1px solid black;
}
span {
border: 1px solid black;
border-radius: 50%;
position: absolute;
top: calc(50% - 20px);
left: -10px;
cursor: pointer;
height: 40px;
width: 40px;
display: inline-block;
background: white;
}
I am not sure if you already solved this issue, but since you helped me on the other question, I am interested in helping you with this.
You have some options.
Use pure JavaScript. You can use a lib (eg: this) for that.
Use Jquery $().draggable() propriety. This might help for styling the button..
Using pure HTML & CSS resize. This is not good, since you cannot apply any style to the <div>.
You can make a workaround mixing three <div> elements,
One of them with position: fixed. This is your background.
Another for the container (with a width set manually to hide the page from user). Remove the scrollbar and force the width of your html, body to match your screen.
Another <div> inside the container for your content. This should be able to move horizontally to show and hide the elements.
I have a scrolling image gallery as follows. The CSS lays out the images in a row that scrolls horizontally. Underneath, I have a row of the same images, but as thumbnails. I want to be able to click on a thumbnail, and scroll the correct image into view.
HTML:
<div class="images_container">
<img id="image_1" src="/image1.jpg">
<img id="image_2" src="/image2.jpg">
<img id="image_3" src="/image3.jpg">
</div>
<div class="images_container thumbnails">
<img src="/image1.jpg" class="thumbnail">
<img src="/image2.jpg" class="thumbnail">
<img src="/image3.jpg" class="thumbnail">
</div>
CSS:
.images_container {
overflow-x: scroll;
overflow-y: hidden;
max-height: 50rem;
white-space: nowrap;
}
.images_container.thumbnails {
max-height: 10rem;
}
.images_container img {
vertical-align: top;
height: 50rem;
}
.images_container.thumbnails img {
height: 10rem;
}
This works up to a point, but jumping to the id of the image is problematic. If the larger image is even a few pixels into the visible viewport, it can't 'jump' to it, as it seems to be technically on the screen.
Is there a way I can use Javascript to 'scroll' the whole image into view when I click on it's corresponding thumbnail? I don't have access to jQuery on this project, but am happy to use JavaScript to make this work.
You can try this , no change in CSS, i add an id in html and call to scrollTo function :
<script>
function scrollTo(image_id){
var topLeft = document.getElementById(image_id).offsetTop;
document.getElementById('container').scrollLeft = topLeft;
}
</script>
<div id="container" class="images_container">
<img id="image_1" src="/image1.jpg" height="500px" width="500px">
<img id="image_2" src="/image2.jpg" height="500px" width="500px">
<img id="image_3" src="/image3.jpg" height="500px" width="500px">
</div>
<div class="images_container thumbnails">
<img src="/image1.jpg" class="thumbnail" onclick="scrollIntoView('image_1')">
<img src="/image2.jpg" class="thumbnail" onclick="scrollIntoView('image_2')">
<img src="/image3.jpg" class="thumbnail" onclick="scrollIntoView('image_3')">
</div>
To keep DOM cleaner I got this solution which requires only adding js
var elms = document.getElementsByClassName("thumbnail");
for (var i = 0; i < elms.length; i++) {
elms[i].onclick = function(event) {
event.preventDefault();
event.stopPropagation();
var id = this.parentNode.href.substr(this.parentNode.href.lastIndexOf('/') + 2);
var v = document.getElementById(id).getBoundingClientRect().left;
document.getElementsByClassName("images_container")[0].scrollLeft += v;
}
}
See on jsfiddle
Here's my attempt at a no (well, minimal) JS solution to a scrolling gallery. You could, in fact, remove the Javascript all together if you replaced the .active class with the :target pseudo-selector, allowing you to click your thumbnails to do the scrolling. It's just easier for me to do it this way through a fiddle
function removeClass(element, className) {
var classes = element.className.split(' ');
var key = classes.findIndex(function(name) {
return name == className
});
classes.splice(key, 1);
element.className = classes.join(' ');
}
function addClass(element, className) {
var classes = element.className.split(' ');
classes.push(className);
element.className = classes.join(' ');
}
setInterval(function() {
var current = document.querySelector('.images .image.active');
var next = current.nextElementSibling;
if (!next) {
next = document.querySelector('.images .image:first-child');
}
removeClass(current, 'active');
addClass(next, 'active');
}, 1500);
body {
margin: 0;
padding: 0;
width: 500px;
height: 500px;
}
.images {
width: 100%;
height: 100%;
position: relative;
overflow-x: hidden;
}
.image {
width: 100%;
height: 100%;
top: 0px;
position: absolute;
left: -100%;
float: left;
transition: 1s;
}
.image.active {
left: 0%;
}
.image.active ~ .image {
left: 100%;
}
.black {
background-color: black;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
<div class='images'>
<div class='image black active'></div>
<div class='image red'></div>
<div class='image blue'></div>
<div class='image yellow'></div>
</div>
Essentially the way it works is by making the div.images container a certain height and width, and therefore all images inside it can be positioned as you want. We initially set all .image to left: -100%, so that they're completely off screen to the left. We then set .image.active as left: 0 so that it's on screen. We then use the ~ selector to say that all siblings that come after the current (.image.current ~ .image) should be left: 100%, so completely to the right. Add in a transition, and you have a completely CSS scrolling gallery. The JS only acts as a way to change what the current active image is, and you can replace that with :target if you want.
I used div's, instead of img tags because it's easier to provide a POC with div's and background colors, but it's worked well with images in the past. Just put an <img> tag inside those <div class='image'></div> tags
I want to scale image proportionally to fit parent
What I'm getting is:
What I want is:
CSS:
.path {
max-width: 100%;
max-height: 100%;
border: 3px solid #d7d7d7;
cursor: pointer;
}
HTML:
<div>
<ul>
<li class="li_parent"><div class="div_parent"><img class="path" src="path/path1.jpg"></div></li>
<li class="li_parent"><div class="div_parent"><img class="path" src="path/path2.jpg"></div></li>
<li class="li_parent"><div class="div_parent"><img class="path" src="path/path3.jpg"></div></li>
</ul>
</div>
Javascript:
$(".div_parent").css( { "width" : Math.ceil($(document).width()*0.3)+"px" } );
$(".div_parent").css( { "height" : Math.ceil($(".div_parent").width()/2.24)+"px" } );
I want path class (images) to fit to div_parent proportionally...
You are resizing the .div_parent elements, but you never specify that you want the img elements to fill their .div_parent. Instead of using max-height and max-width, use:
.path {
height: 100%;
width: 100%;
}
Also, instead of using img elements to display images, you can set the background-image of your .div_parent (or li) elements (background-image: url(path.jpg)). This way you can control image size with background-size CSS3 property.
Edit: use CSS background like this:
<ul class="gallery">
<li style="background-image: url(path1.jpg)"></li>
<li style="background-image: url(path2.jpg)"></li>
<li style="background-image: url(path3.jpg)"></li>
</ul>
with:
.gallery li {
background-size: cover;
}
And set li sizes as you wish with CSS or JavaScript.
Edit2: If you need IE7/8 support, use the following HTML:
<ul class="gallery">
<li style="
background-image: url(path1.jpg);
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path1.jpg', sizingMethod='scale');
-ms-filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path1.jpg', sizingMethod='scale')"
"></li>
</ul>