I am using a grid gallery for my web based application. The gallery doesn't have a description box for the image and I don't figure how to manually add one.
If I try to add a div inside the <div class="content"></div> which holds my image, the image fails to load in full view when click. I tried multiple methods, even went through some tricks and tutorials on the web but nothing seemed to work. Even if the div inside the content class loads, it takes the width of the entire full screen (more than the width of the image).
All the images have a separate width and height so I can't fix the width too. Here is a sample of what I want to achieve and my current codes in codepen snippet.
Here is the Sample: https://prnt.sc/plhqcr
Code Pen Snippet: https://codepen.io/zoomkraft/pen/KKKNVXN
This description box is what I want in FULL VIEW of the image (single image when clicked for full view) and not on the gallery view. Any help would be highly appreciated.
Now I think it is the 10th time I see this codePan Snippet and the question to add a description box. So I figuered out and get the following step-by-step solution:
Changes in HTML
Add a Div with the class: .desc as a child to every Div with the class od .gallery-item. The New Div .desc holds the Description.
<div class="gallery-item">
<div class="content">
<img src="https://source.unsplash.com/random/?tech,care" alt="">
<div class="desc">This is my Image Description</div>
</div>
</div>
Changes in CSS
Set the img display type in the class ".full .content" (.full .content img {) to block. Also set the mas-height to 80%.
.full .content img {
left: 50%;
display:block;
transform: translate3d(0, 0, 0);
animation: zoomin 1s ease;
max-width: 100%;
max-height: 80%;
margin: auto;
}
Now add the classes for .content .desc and .full .content. desc
.content .desc {
display:none;
height:20%;
}
.full .content .desc {
display:block;
height:20%;
margin-right:auto;
margin-left:auto;
background:#fff;
}
Changes to JS
Code first ...
var gallery = document.querySelector("#gallery");
var getVal = function(elem, style) {
return parseInt(window.getComputedStyle(elem).getPropertyValue(style));
};
var getHeight = function(item) {
return item.querySelector(".content").getBoundingClientRect().height;
};
var resizeAll = function() {
var altura = getVal(gallery, "grid-auto-rows");
var gap = getVal(gallery, "grid-row-gap");
gallery.querySelectorAll(".gallery-item").forEach(function(item) {
var el = item;
el.style.gridRowEnd =
"span " + Math.ceil((getHeight(item) + gap) / (altura + gap));
});
gallery.querySelectorAll(".full").forEach(function(item) {
var imgwidth = item.getElementsByTagName('img')[0].clientWidth;
var desc = item.getElementsByClassName('desc')[0];
desc.style.width=imgwidth+"px";
});
};
gallery.querySelectorAll("img").forEach(function(item) {
item.classList.add("byebye");
if (item.complete) {
console.log(item.src);
} else {
item.addEventListener("load", function() {
var altura = getVal(gallery, "grid-auto-rows");
var gap = getVal(gallery, "grid-row-gap");
var gitem = item.parentElement.parentElement;
gitem.style.gridRowEnd =
"span " + Math.ceil((getHeight(gitem) + gap) / (altura + gap));
item.classList.remove("byebye");
});
}
});
window.addEventListener("resize", resizeAll);
gallery.querySelectorAll(".gallery-item").forEach(function(item) {
item.addEventListener("click", function(event) {
if ((item.classList.contains("full") && ['IMG', 'A'].includes(event.target.tagName)) || (item.classList.contains("full") && ['desc'].includes(event.target.className))) {
return;
}
item.classList.toggle("full");
var imgwidth = item.getElementsByTagName('img')[0].clientWidth;
var desc = item.getElementsByClassName('desc')[0];
desc.style.width=imgwidth+"px";
});
});
To the resizeAll function we added a small snippet to resize the .desc class if screen is resizing by the image width.
In the .gallery-item click function we add a small code to size the div after toggle.
Thats all and for me at works fine and meets your requirements.
Here you will find the updated Code Pen: https://codepen.io/MatWer/pen/XWWNGoK (With only the first Item has the desc .class)
Related
I'm trying to set a div's height in relation to another div. 'gridimg' has an image in it and 'gridtext' has text so when the page is resized, the div containing the text changes height. I have the following code in a .js file:
window.onresize = function resize() {
var right = document.getElementById('gridimg').style.height;
var left = document.getElementById('gridtext').style.height;
document.getElementById('gridimg').style.height=left;
});
I'm trying to get it to call this function when the window is resized so the divs stay the same size but it's not working. I'm new to external javascript so could anyone help me :)
If you want to read an element height, you have to use the offsetHeight property. The style.height is for setting the height.
http://codepen.io/bajzarpa/pen/oZVOrL
I would write a function to check for resize and get the #gridimg height like this answer: Call a function when window is resized
Then watch for it like this:
$(window).resize(function () {
yourMethod( $('#gritext'));
});
Similar: https://stackoverflow.com/a/15205712/6254070
Here's a code snippet showing how to do that, based loosely on the W3 Tryit:
<!DOCTYPE html>
<html>
<body onresize="myFunction()">
<style>
#thetext {
width: 100%;
height: 50px;
display: block;
clear: both;
overflow: hidden;
}
#otherdiv {
background-color: green;
display: block;
clear: both;
overflow: hidden;
}
</style>
<p>Try to resize the browser window to display the windows height and width.</p>
<p id="demo"></p>
<div id="thetext"><strong>Note:</strong> this example will not work properly in IE8 and earlier. IE8 and earlier do not support the outerWidth/outerHeight propery of the window object.</div>
<div id="otherdiv"></div>
<script>
function myFunction() {
setTimeout(function() {
var sourceEl = document.getElementById('thetext');
var targetEl = document.getElementById('otherdiv');
var newHeight = sourceEl.offsetHeight;
// || sourceEl.getBoundingClientRect().height;
targetEl.width = sourceEl.offsetWidth;
targetEl.style.height = newHeight + 'px';
var w = targetEl.offsetWidth;
var h = targetEl.offsetHeight;
var txt = "Target size: width=" + w + ", height=" + h;
document.getElementById('demo').innerHTML = txt;
}, 0);
}
</script>
</body>
</html>
I have 2 divs, a navigation and a main content in a bootstrap grid system. The length of either can vary depending on amount of content. I need them both styled to fill 100% of the browser window IF neither has the content to reach the bottom naturally. But if at least one of the divs has more content than the length of the browser window, I need to be able to scroll down the page with the styles of both divs remaining in tact and both have a height of the longer of the 2 divs.
I'm currently using a javascript resize function which seems to work but not in the case where neither div is long enough to fill the height of the browser window. Any suggestions?
HTML
<div class="row">
<div id="nav" class="col-xs-2">
Variable Height Navigation
</div>
<div id="main" class="col-xs-10">
Variable Height Content
</div>
</div>
Javascript
function resize() {
var h = (document.height !== undefined) ? document.height : document.body.offsetHeight;
document.getElementById("nav").style.height = h + "px";
}
resize();
window.onresize = function () {
resize();
};
I am trying to understand you question, and if I'm correct what you are looking for is:
Both divs need to be equally high
They need be at least the height of the screen
They need to take the height of the highest div
So let's try to achieve this goal as simply as possible:
var main = document.getElementById('main');
var nav = document.getElementById('nav');
function resize(){
var highest;
// Set the divs back to autosize, so we can measure their content height correctly.
main.style.height = 'auto';
nav.style.height = 'auto';
// Find the highest div and store its height.
highest = main.clientHeight > nav.clientHeight
? main.clientHeight
: nav.clientHeight;
// Check if the highest value is the div or the window.
highest = highest > window.innerHeight
? highest
: window.innerHeight;
// Assign the newly found value
main.style.height = highest + 'px';
nav.style.height = highest + 'px';
}
resize();
// Also, you don't need to wrap it in a function.
window.resize = resize;
// However, better would be:
window.addEventListener('resize', resize, false);
#main, #nav {
width: 100%;
height: auto;
}
#main { background: red; }
#nav { background: green; }
<div id="main"></div>
<div id="nav"></div>
Now, If you aren't bothered with the actual sameness in heiught of both divs but just want them to at least be one screenful, you should consider using CSS:
html, body { height: 100%; }
#nav, #main { min-height: 100%; }
I think that is the better solution (no Javascript!) and sort-of does what you want, bar the fact that you won't have to equally high div elements. However, you would barely notice it as each will at least fill the page.
You could try using viewport height:
For example:
#nav {
min-height: 100vh;
}
#main {
min-height: 100vh;
}
See Bootply.
This will also remove the need for JavaScript.
My situation is this:
I have a large container the size of the screen which is static and has overflow:hidden. Inside is a very large div that is jqueryui-draggable. Inside that are many many small divs.
The small divs are all hidden by default, I'd like them to appear when they move into the viewport(top parent container) and disappear when moved out. Keep in mind all the moving is done by dragging the very large middle div.
Most of the solutions I've found only work on page scroll. Is there some sort of event I could bind to the draggable?
Disclaimer
I haven't tested this, but hopefully it at least gives you a direction.
The biggest concept to grasp is to check each child to determine whether it is fully within the viewport every time the .drag() method is called on your draggable container. You can modify the logic to fade your elements in / out as needed or to allow the child to be considered visible even before it is fully within view.
CSS
.parent {
position: absolute;
overflow: hidden;
height: 5000px; /* example */
width: 5000px; /* example */
}
.child {
position: absolute;
height: 50px;
width: 50px;
}
HTML
<body>
<div class='parent'>
<div class='child'></div>
<div class='child'></div>
<div class='child'></div>
<!-- ... -->
</div>
</body>
JQUERY
$( ".parent" ).draggable({
drag: function( event, ui ) {
var parentTop = ui.position.top;
var parentLeft = ui.position.left;
var windowHeight = $(window).height();
var windowWidth = $(window).width();
$('.child').each(function(index) {
var childTop = $(this).position().top;
var childLeft = $(this).position().left;
var childWidth = $(this).width();
var childHeight = $(this).height();
// check whether the object is fully within the viewport
// if so - show, if not - hide (you can wire up fade)
((childLeft >= -(parentLeft) && childTop <= -(parentTop) &&
(childLeft + childWidth) <= (-(parentLeft) + windowWidth) &&
(childTop + childHeight) <= (-(parentTop) + windowHeight)))
? $(this).show()
: $(this).hide();
});
}
});
I have a banner enclosed in a div tag that contains my banner. I would like to get the banner to fade to the next image but unsure how to achieve the fading effect. I have tried using jQuery fadeIn() but it failed.
The reason why I need to use the background: url() is because I want this banner image to resize pleasantly when the browser gets resized. I am not sure if this is the best way of approaching my problem.
EDIT - My current code does swap the images in the banner, but does not apply the fadeIn() effect. The console does not report any errors.
CSS:
header div#banner {
background: url(../image/banner/00.jpg) no-repeat center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
height: 300px;
}
JavaScript:
var bannerImages = new Array();
var bannerCounter = 0;
function run() {
loadBannerImages();
runBannerTimer();
}
function loadBannerImages() {
var filePath = "image/banner/";
bannerImages[0] = filePath + "00.jpg";
bannerImages[1] = filePath + "01.jpg";
bannerImages[2] = filePath + "02.jpg";
bannerImages[3] = filePath + "03.jpg";
bannerImages[4] = filePath + "04.jpg";
}
function runBannerTimer() {
var t=setTimeout("swapBannerImage()",2000);
}
function swapBannerImage() {
$('#banner').fadeIn(1000, function() {
$('#banner').css('background', 'url(' + bannerImages[bannerCounter] + ') no-repeat center');
});
bannerCounter++;
if (bannerCounter >= bannerImages.length) {
bannerCounter = 0;
}
runBannerTimer();
}
Your setTimeout isn't correct; try the following instead:
function runBannerTimer() {
var t=setTimeout(function(){
swapBannerImage()
},2000);
}
EDIT
Here is the updated Banner Swap function:
function swapBannerImage() {
$('#banner').fadeOut('slow', function(){
$('#banner').css('background', 'url(' + bannerImages[bannerCounter] + ') no-repeat center').fadeIn('slow');
});
bannerCounter++;
if (bannerCounter >= bannerImages.length) {
bannerCounter = 0;
}
runBannerTimer();
}
Updated Demo Here
You could use multiple divs -- one per image -- and fade them in/out. The divs could still use the css background like you want, you'll just need to absolutely position them, so that they appear one on top of another. However, to get absolutely positioned divs to resize with the parent div (ie to get the "pleasant" resizing effect), you have to set up the css like so:
header div#banner {
... /* your background stuff here */
position: absolute;
left: 0;
right: 0;
height: 300px;
}
Note that you'll assign both left and right, which would make it take up the entire width of the parent. And, make sure that the parent has position:relative.
Let's say I have a single HTML page. 2000 pixels long for example. I want to detect if a visitor reaches a certain point on the page.
The page structure:
0px = begin of the page;
500px = about us page;
1000px = contactpage;
Is there a way with jQuery to detect if a user reaches the points described above?
You probably want jQuery's scroll event-binding function.
Yes, I would create three divs and then have a mouse over event on each. Example:
$("#begin").mouseover(function(){
alert("over begin");
});
$("#about").mouseover(function(){
alert("over about");
});
$("#contact").mouseover(function(){
alert("over contact");
});
You can see a working fiddle here: http://jsfiddle.net/ezj9F/
Try THIS working snippet.
Using this code you don't have to know position of the element you want to check if it is visible.
JQuery
var $window = $(window);
// # of pixels from the top of the document to the top of div.content
var contentTop = $("div.content").offset().top;
// content is visible when it is on the bottom of the window and not at the top
var contentStart = contentTop - $window.height();
// content is still visible if any part of his height is visible
var contentEnd = contentTop + $("div.content").height();
$window.scroll(function() {
var scrollTop = $window.scrollTop();
if(scrollTop > contentStart && scrollTop < contentEnd) {
console.log('You can see "HELLO"!');
} else {
console.log('You cannot see "HELLO"!');
}
});
HTML
<div class="scroll"></div>
<div class="content">HELLO</div>
<div class="scroll"></div>
CSS
div.scroll {
background-color: #eee;
width: 100px;
height: 1000px;
}
div.content {
background-color: #bada55;
width: 100px;
height: 200px;
}
EDIT: Now the algorithm is checking if any part of the div.content is visible (it is considering height of the element). If you are not interested in that change contentEnd to var contentEnd = contentTop.