Calculation Returns Multiple Values - javascript

I have a jQuery function that checks the values of the child images heights, then sets the parents height to the value of the smallest image's height, then adds overflow: hidden to avoid overflow.
I execute the function from the document.ready event, however I am getting odd results. I will get HTMLobjectHeight, 0, undefined, or the correct value on a pageload. Why is this varying? is it firing before the images are loaded?
function setContainHeight()
{
var container = $('.com-background');
var imgs = $('.com-background img');
var smallestImg = imgs[0];
$(imgs).each(function()
{
if ($(this).height() < $(smallestImg).height() )
smallestImg = $(this).height();
});
container.height(smallestImg);
container.css("overflow", "hidden");
};
One other issue I am having is, when I add this function to the window.resize event it also fires on pageload, and gives an undefined result.
HTML
<div class="com-background" style="height: 434px; overflow: hidden;">
<h1 class="community_title">Sun Lakes</h1>
<img width="250" height="167" src="http://192.168.33.10.xip.io/wp-content/uploads/2013/04/Ocotillo-lake-e1404789921289.jpg" class="wp-post-image" alt="Ocotillo - lake" style="display: block; z-index: 1;">
<img width="250" height="188" src="http://192.168.33.10.xip.io/wp-content/uploads/2013/04/Resort-e1404789892490.jpg" class="attachment-post-secondary-image-thumbnail active" alt="Resort" style="z-index: 3; opacity: 0.988634061784097;">
<img width="837" height="378" src="http://192.168.33.10.xip.io/wp-content/uploads/2014/05/homestead-error.png" class="attachment-post-tert-image-thumbnail" alt="homestead-error" style="z-index: 2;"> <div class="numeric_search">
</div>
SASS/CSS
.com-background
{
width: 100%;
position: relative;
img
{
z-index: 1;
position: absolute;
top: 0;
left: 0;
width: inherit;
max-width: 100%;
height: auto;
}
}

To make sure the images have been loaded, start with a $(window).load event listener
I'd also use Math.min to get the lowest image height
$(window).on("load resize", function(event) {
// find container
var container = $(".com-background");
// get image heights in an array
var heights = container.find("img").map(function(idx, elem) {
return $(elem).height();
}).get();
// get the minimum height
var minimum = Math.min.apply(null, heights);
// set container height and overflow property
container.height(minimum).css({overflow: "hidden"});
});

If you want get all of height of images , you need to be sure that all images was downloaded and ready to used ... To be sure, you need use $(window).load() instead of $(document).read like that:
$(window).load( function() {
setContainHeight();
$(window).resize( setContainHeight );
});

Related

How to resize canvas using his height and width attribute on every time it's get resize

I have the below canvas which is getting updated whenever the div gets resized.
window.addEventListener('resize',function()
{
let mapwidth = $('.canvas').attr("width")
let mapHeight = $('.canvas').attr("height")
console.log(mapwidth ,mapHeight)
$('.canvas').css("width",mapwidth);
$('.canvas').css("height",mapHeight);
});
canvas
{
border: solid black 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas class="canvas" tabindex="0" width="511" height="333" style="position: absolute; left: 0px; top: 0px;"></canvas>
<br>
<canvas class="canvas" tabindex="0" width="232" height="1333" style="position: absolute; left: 0px; top: 0px;"></canvas>
but it's not working somehow I am only getting 0 0
my question is how I get the current canvas height and width in the
inline style.
now the same height and width get applied on all the canvas, but I want different for all canvas base on their attribute
So, since you want to do this for .each() .canvas class element, you are going to have to use the jQuery selector ($(".canvas")) to select all those classes, then iterate over them with the .each() method.
Example:
$(".canvas").each(function()
{
console.log(this.height, this.width);
});
The above will print the current width and height for each .canvas element.
Furthermore, you can add logic based on the attributes you want, example:
$(".canvas").each(function()
{
console.log(this.height, this.width);
if ($(this).attr("height") > 50)
{
console.log("Greater than 50.");
}
else
{
console.log("Not greater than 50.");
}
// You can also use the ternary operator to shorten the above if statement to:
// $(this).attr("height") > 50? console.log("Greater than 50."): console.log("Not greater than 50.");
});
Below is an example of the first code snippet - you'll have to resize the page for it to do anything, of course.
window.addEventListener('resize',function()
{
$(".canvas").each(function()
{
console.log(this.height, this.width, "these are the values set for the physical canvas space")
$(this).css("height", 100 + "px")
console.log(this.style.height, this.style.width, "these are the physical inline styles for each of the canvas elements; notice width hasn't been set yet.");
// there are 3 ways you can set width - the first one is the same way we set height:
// $(this).css("width", 100 + "px");
// the second will let you set the !important flag, if you need to (which is my preference):
// this.style.setProperty("width", value);
// this.style.setProperty("width", value, "important");
// lastly, you could do (I think):
// this.style.height = value;
});
});
canvas
{
border: solid black 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas class="canvas" tabindex="0" width="511" height="333" style="position: absolute; left: 0px; top: 0px;"></canvas>
<br>
<canvas class="canvas" tabindex="0" width="232" height="1333" style="position: absolute; left: 0px; top: 0px;"></canvas>
EDIT 1:
I think that the event listener is being added twice to this code snippet, not because of the code itself, but maybe the SO page runs the snippet before hand to load it?
EDIT 2:
You should have a few option for setting the inline styles - here they are:
This option -> $(this).css("width", 100 + "px");
This option -> will let you set the !important flag, if you need to (which is my preference)
this.style.setProperty("width", value); (make sure to include the units)
this.style.setProperty("width", value, "important"); (make sure to include the units)
I think this is an option for inline styling as well -> this.style.height = value; (make sure to include the units)

Yet Another Image Slider JQuery Issue

I have trying for some time. And I gave a look at the image slider questions already. But I would really appreciate if I get some specific help here. Please tell me where the following code went wrong.
Here's my jQuery code:
function slideMe {
$('.imgcontainer').animate({"margin-left":"-= 100%"}, 2000, function () {
if($('.imgcontainer').css("margin-left") == (-300%)) {
$('.imgcontainer').css("margin-left", "0px");
}
slideMe();
});
}
window.onload = slideMe();
And here's the script on HTML page:
<div class="fitimage">
<div class="imgcontainer">
<img src="img/copywrtng.jpg" class="headerimage" alt="copywriting" />
<img src="img/copywrtng1.jpg" class="headerimage" alt="copywriting" />
<img src="img/copywrtng2.jpg" class="headerimage" alt="copywriting" />
</div>
</div>
And here's what I have on CSS:
div.fitimage {
width:100%;
height:93vh;
overflow: hidden;
}
img.headerimage {
padding: 0;
margin:0 auto;
width:100%;
/*max-height:100%;
max-width:100%;*/
height:93vh;
}
My logic is that as each image takes up 100% width, as the ".imgcontainer" div slides left with margin-left: -100%, each image should come up one by one from the right, until it reaches the last one when it reverts to the first image again.
It's not working!
Please help.
Your "main" issue is in this line:
$('.imgcontainer').css("margin-left") == (-300 % )
// ^^^^^^^^
beside you can only use string format "-300%", .css("margin-left") will give you a px value which you cannot compare with a non-computed %.
Another issue is that the slides set at 100% - will be the width of their container, which might be actually greater (300% for 3 slides).
Solution:
Instead I'd suggest you to use a c counter that goes like 0,1,2, 0,1... etc.
Than calculate the overflow-wrapper width and animate scrollLeft: width * counter (instead of -marginLeft).
Use display:flex on the parent and min-width:100%; on the child DIV elements (than place your images inside those DIVs instead!)
$(".imgcontainer").each(function(){ // Now you can have multiple independent sliders!
var $gal = $(this),
$slides = $gal.children(), // get the slides
tot = $slides.length, // number of slides
c = 0; // the counter we mentioned
(function anim() { // internal animation callback function
var w = $gal.width();
c = ++c % tot; // increment or loop-back counter to 0
$gal.delay(2000).animate({scrollLeft: w*c }, 1000, anim); // anim callback !
}()); // << START!
});
/*QuickReset*/ *{margin:0;box-sizing:border-box;font:14px/1.4 sans-serif;} html,body{height:100%;}
.imgcontainer{
position:relative;
height: 93%; /* or whatever you see fit */
display: flex;
overflow: hidden;
}
.imgcontainer > div {
min-width: 100%;
background: none 50% 50% / cover;
/* Set background-image inline (see HTML) */
/* Or use inner images like you did */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="imgcontainer">
<div style="background-image:url(http://placehold.it/500x340/0bf);">
Slide 1
</div>
<div style="background-image:url(http://placehold.it/500x340/f0b);">
Slide 2
</div>
<div style="background-image:url(http://placehold.it/500x340/b0f);">
Slide 3
</div>
</div>

Jquery: Slide images diagonally

Here is the effect I want to achieve:
This is i.e. one image, and the other images should slide diagonally in the way that arrow goes. The effect should not be fade effect. The slide effect has to be achieved.
Here is the html:
<div id="slider_page">
<div style="display: block;">
<img src="img1.jpg">
<img src="img2.jpg">
</div>
</div>
Please for help guys.
Sorry for the mess in the html code.
Thanks in advance
Here is a rough sketch on how to do it on your own, without a library. The code might need some adaption for your particular circumstances. For instance, if you want to slide not only images but elements containing text as well, change from using <img> to <div>. You'll find explanation in the comments.
HTML
<div id="carousel">
<img class="carousel-img" src="img1.jpg" />
<img class="carousel-img" src="img2.jpg" />
<img class="carousel-img" src="img3.jpg" />
</div>
CSS
#carousel {
position: relative; /* So images are positioned relative to it. */
width: 400px;
height: 300px;
overflow: hidden; /* So we clip the other images. */
}
.carousel-img {
width: 100%;
position: absolute; /* Position relative to parent div. */
left: 400px; /* Hide just beyond bottom right corner. */
top: 300px;
}
.carousel-img:first-child {
/* Do not hide the first image. */
left: 0px;
top: 0px;
}
JavaScript
//Some settings.
var animation_time = 500; //Millisecs the animation takes.
var waiting_time = 2000; //Millisecs between animations.
//Some variables.
var images; //A list of the images.
var i = 0; //Index of the current image.
var w; //Width of carousel.
var h; //Height of carousel.
$(function() {
//Runs when the DOM is ready.
//Set the variables.
images = $("#carousel .carousel-img");
w = $("#carousel").css("width");
h = $("#carousel").css("height");
//Start the carousel.
setTimeout(slideToNext, waiting_time)
});
function slideToNext() {
//Get the index of the next image.
var next = (i + 1) % images.length;
//Make sure the new image is on top.
images.css("z-index", 0);
images.eq(next).css("z-index", 1);
//Animate the next image.
images.eq(next).animate({left: "0px", top: "0px"}, animation_time, function() {
//Runs when the animation is compleated.
//Move the old image out.
images.eq(i).css({left: w, top: h});
//Now this is the current image.
i = next;
//Do it again.
setTimeout(slideToNext, waiting_time);
});
}
Here is a working JSFiddle, including some beautiful artwork by Caspar David Friedrich.
It might also be possible to configure an existing carousel library (like Slick or Jssor) to do this.

Display images vertically until end of page, then continue horizontally within 100% height responsive div

I am using the following code which displays images vertically within a div that has 100% height and a auto width. I want the images to be displayed vertically until the end of the page and then start displaying horizontally. I want the content div width to be automated based on how many images are displayed but always have the 100% height. At the moment the images are displayed vertically until the page ends and then the rest of the images are hidden in the overflow.
#content {
min-height: 100%;
display: table;
width: auto;
overflow-y: hidden;
}
#thumbnailgrid {
overflow-y: hidden;
height: 100%;
max-height: 100%;
width: auto;
}
#thumbnailgrid img {
width: auto;
height: 24%;
}
Ok this is what I came up to, you might want to modify it a bit to fit your needs because this one doesn't keep track of margins or paddings, but it should help you solve your problem: http://jsfiddle.net/crbmL7sb/4/
To see it working try resizing the result window and clicking on "Run" again. You might want to add a window resize event listener as well.
Here's the HTML:
<div class="wrapper">
<div class="single">
<img src="http://placehold.it/200x200&text=A1" alt="placeholder" />
<img src="http://placehold.it/200x200&text=A2" alt="placeholder" />
<img src="http://placehold.it/200x200&text=A3" alt="placeholder" />
<img src="http://placehold.it/200x200&text=A4" alt="placeholder" />
<img src="http://placehold.it/200x200&text=A5" alt="placeholder" />
</div>
<div class="single">
<img src="http://placehold.it/200x200&text=B1" alt="placeholder" />
<img src="http://placehold.it/200x200&text=B2" alt="placeholder" />
<img src="http://placehold.it/200x200&text=B3" alt="placeholder" />
<img src="http://placehold.it/200x200&text=B4" alt="placeholder" />
<img src="http://placehold.it/200x200&text=B5" alt="placeholder" />
</div>
</div>
The Javascript:
var CL = function( vals ) {
columns = vals.columns;
var wHeight = $(window).height();
this.init = function() {
this.createColumns();
this.setBodyWidth();
}
this.createColumns = function() {
//loop through all the big columns
for(var i=0, l=columns.length; i < l; i++) {
images = $(columns[i]).find("img"); //get all the images in this column
columnHeight = 0; //set a flag to store the column height
var newDiv = $("<div />").addClass("inner"); //create an inner div inside the column
for (var p=0, n=images.length; p < n; p++) { //loop through all the images in this column
columnHeight += $(images[p]).height(); //add the height of the current image to the column height flag
if (columnHeight >= wHeight) { //compare the column height with the window height, if there's NOT enough room for the new image
newDiv.appendTo($(columns[i])); //append this column to the big parent div
var newDiv = $("<div />").addClass("inner"); //create a new column
columnHeight = $(images[p]).height(); //reset the column height flag
}
$(images[p]).appendTo(newDiv); //add the image to the current column
}
// THIS IS THE LINE I FORGOT
newDiv.appendTo($(columns[i]));
}
}
this.setBodyWidth = function() {
//when moving the images in the appropriate divs is done
var totWidth = 0;
$(".inner").each(function() {
totWidth += $(this).width(); //get the width of all the content
}) //and set it to the main wrapper to create the horizontal scrollbar
vals.wrapper.css({
width: totWidth
})
}
this.init();
}
//You need to somehow preload the images, or this will not work. Maybe add an overlay to cover the page while the images are being loaded and then fade it out. A simple window load even (like I commented out below) should work, but it appears to be broken on jsfiddle.
//$(window).load(function() {
var cl = new CL({
columns: $(".single"),
wrapper: $(".wrapper")
});
//});
And a little bit of CSS
img {
display: block;
}
.inner {
float: left;
}
img {
border: 4px solid white;
}
* {
box-sizing: border-box;
}

identifying when items are in view and out of view on website

I am building some code to try and have something happen when an image is within view, then reset the counter when the image isnt in view and have that same thing happen again if the image returns to view.
I have the code working to recognize when the image comes into view and do something, but then when I add the code to reset the counter when the image is out of view the whole thing stops working.
html:
<div style="height: 2000px">
<img height="320px" width= "240px" id="pbr" src="http://i47.tinypic.com/33bztj8.jpg" alt="image 1">
<img height="320px" width= "240px" id="pbrglow" src="http://i48.tinypic.com/2ykduvl.jpg" alt="image 2">
<button id="button">click to reset</button>
</div>
css:
#pbr {
position: absolute;
top: 500px;
z-index: 0;
}
#pbrglow {
position: absolute;
display: none;
top: 500px;
z-index: 1;
}
#button {
position: absolute;
top: 850px;
z-index: 3;
}
javascript:
var y = $("#pbr").offset().top;
var eventsFired = 0;
$(window).scroll(function() {
var y = $("#pbr").offset().top;
var scrollY = $(window).scrollTop();
if (scrollY + 100 > y && eventsFired == 0) {
eventsFired++;
alert(eventsFired);
}
});
$("#button").on("click", function() {
var scrollYY = $(window).offsetTop();
if (eventsFired == 1) {
alert("happened");
eventsFired = 0;
}
}
Here is the jsfiddle with the code
Once I remove the code starting in $("#button")... the code works, but with this in the code doesnt.
P.S. this is a website I need to work on iOS.
That's because your #button click handler is throwing an error:
Uncaught TypeError: Object [object Object] has no method 'offsetTop'
You can see it on the jsFiddle page if you have a console open (you can enable the console for mobile Safari via Settings->Safari->Developer).
That problem is that $(window) doesn't have an offsetTop() method. If you get rid of that line (and you don't need it anyway, since you're never using scrollYY), everything works.

Categories