How to get height of element with dynamically loaded images inside - javascript

I have a lot of tables and in last td in last tr I put message from back-end. There could be not only text, but the images (url to them in tags), so they load dynamically. I need to get the height of this table and if it more than 400 I add some contant.
Firstly, I did this:
$("table[name]='forum'").each(function() {
var height = $(this).height();
if (height > 400) {
var redirect = $("#backUrl").val() + "#" + $(this).find("[name]='answ'").attr("id");
$(this).find("tr:last-child > td:last-child").append(function() {
return "<div></div><a style='float: right' href='"+ redirect + "'><img src='/images/arrow_up.png'></a>";
});
};
});
But it didn't work for tables with images. Than I googled that for img I should use load() and add:
$(this+"> img").load(function() {
height += $(this).height();
});
but I understand, that this is wrong, cause img could be loaded after this block is done. I did some other actions, but it won't affect as I wanted.
What is the solution of this problem? Because it calculates height of whole element without img tag.

To get the final table height(if the img will affect the height, or you can pre-set some max height maybe), you must wait all images loaded.
var table = $(this), imgs = table.find("img"), len = imgs.length;
imgs.one('load', function() {
len--;
//now all image loaded
if (len == 0) {
//here you got the final height
height = table .height();
//do stuffs here
}
}).each(function() {
if (this.complete)
$(this).load();
});

$(this).find("img").load(function() {
height += $(this).height();
});

Related

First image in <body> greater than 200 px Using Jquery

For social media sharing I am trying to get the first image URL which is greater than 200px using jQuery. This is my code which is not working:
$("body img").each(function() {
var $minHeight = 200;
if ($(this).height() > $minHeight) {
$(this).attr('src')
}
});
After getting the right image I need to change the default image URL in content="default-image.png" below:
<meta property="og:image" name="twitter:image" content="default-image.png"/>
This is a working selector for meta tag I found:
$('meta[property=og\\:image]').attr('content','new-image.png');
I Found My Code Is Working But...
$("body img").each(function() {
var $minHeight = 200;
if ($(this).height() < $minHeight) {
$x = $(this).attr('src')
}
});
$('meta[property=og\\:image]').attr('content',$x);
$(".share a[href*='pinterest']").prop("href","https://pinterest.com/pin/create/button/?url=http://mywebsite.com/mypage&media="+$x);
But above script is not working with greater than sign as needed if ($(this).height() > $minHeight)
So, when you do $("body img") jquery returns an array of elements.
If I am understanding it correct, you need the image which is of ACTUAL HEIGHT but not the CSS provided height. In this case:
var ImagesGreaterThan200Height =jQuery.grep($("body img"), function( img, i ) {
if(img.naturalHeight > 200)
return img;
});
From the above code, you will get an array of Images which are greater than 200px in height and for the first image you just need to do:
ImagesGreaterThan200Height[0] // This returns the first Image
Hope this helps!

jQuery addClass not working on DOM fired from JS

Basically I have a menu HTML code that is injected into the DOM via a jQuery function, i.e.
$.get("/clients/nav_menu.html", function(data) {
$("nav").html(data);
$('#side-menu').metisMenu(); //menu plugin for Bootstrap
});
However, after changing the loading of menu to the above script, the Bootstrap distribution package (sb-admin-2) that came with the below lines of code failed during load only (resize continues to work fine) for the code marked (*******) below:
$(function() {
$(window).bind("load resize", function() {
topOffset = 50;
width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
if (width < 768) {
$('div.navbar-collapse').addClass('collapse'); // *******
topOffset = 100;
} else {
$('div.navbar-collapse').removeClass('collapse');
}
height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1;
height = height - topOffset;
if (height < 1) height = 1;
if (height > topOffset) {
$("#page-wrapper").css("min-height", (height) + "px");
}
});
var url = window.location;
var element = $('ul.nav a').filter(function() {
return this.href == url;
}).addClass('active').parent().parent().addClass('in').parent();
if (element.is('li')) {
element.addClass('active');
}
});
The piece of code marked (*******) above fires during load and resize, and div.navbar-collapse resides in the menu HTML code that was injected as mentioned above. I just don't understand why it fails to modify the DOM element during load, but once I resize the screen width, the class 'collapse' gets added to the div.
What I've tried:
made sure that each time I reload the page, the screen size is less than 768px - didn't work;
bringing the code marked (*******) to the end of all my js scripts - didn't work;
bringing the code marked (*******) into the $.get callback right after the menu was loaded - didn't work;

Add different class name to images based on their layout orientation with javascript?

I'd like to use plain javascript to apply either the class name portrait or landscape to all <img> elements with a certain class name based on whether the image file itself is taller than it is wide (portrait orientation) or wider than it is tall (landscape orientation).
I know I can get all of the elements by class name like so:
var portalPics = document.getElementsByClassName("portal-pic");
And I think I can tell the orientation of each image file by comparing the naturalHeight and naturalWidth properties of the HTMLImageElement, but I'm not sure how.
Can anyone help me write the script that I would insert before the closing </body> tag in my HTML document that would automatically add the desired class names to the desired images?
You can just loop, check, and assign:
var portalPics = document.getElementsByClassName("portal-pic");
for (var i = 0; i < portalPics.length; i++) {
if (portalPics[i].naturalWidth > portalPics[i].naturalHeight) {
portalPics[i].className += " landscape";
} else {
portalPics[i].className += " portrait";
}
}
if you compare image width with height, then you know which class to add:
var nodes = document.getElementsByTagName("IMG");
var images = Array.prototype.slice.call(nodes);
images.forEach(function(img) {
if (img.width > img.height) {
img.className += img.className ? ' landscape' : 'landscape';
}
else {
img.className += img.className ? ' portrait' : 'portrait';
}
});

Run a function inside ajax success call back

i have a snippet i created which checks all of the images inside a div and adds a class dependant on their size.
I have this currently on document ready and i works perfectly fine when the page is loaded.
However, im making a CMS where you can edit text on the page itself and then it updates via ajax.
The call response normally looks like:
success: function (response) {
if (response.databaseSuccess) {
$("#container #" +response.postid).load("#container #" +response.postContentID);
$targetForm.find(".saveupdatebutton").qtip("hide");
}
}
After this, the images inside the div that is loaded via the .load() function are not resized.
I have tried putting the code i use in that success response but no luck.
How should i be calling the code after the response?
Heres the code:
$(document).ready(function () {
// check each image in the .blogtest divs for their width. If its less than X make it full size, if not its poor and keep it normal
var box = $(".blogtest");
box.find("img.buildimage").on('load', function () {
var img = $(this),
width = img.width();
if (width >= 650) {
img.addClass("buildimage-large");
} else if (width < 500 && width > 101) {
img.addClass("buildimage-small");
}
// if image is less than X, its most likely a smiley
else if (width < 100) {
img.addClass("buildimage-smiley");
}
}).filter(function () {
//if the image is already loaded manually trigger the event
return this.complete;
}).trigger('load');
});
Depending on which version of jQuery you are using, you might be able to just change .on to .live like this:
box.find("img.buildimage").live('load', function () {
If that does NOT work, then you can try below. Then you'd have to do it the "right" way below:
First externalize your function for the image resizing:
$(document).ready(function () {
// check each image in the .blogtest divs for their width. If its less than X make it full size, if not its poor and keep it normal
var box = $(".blogtest");
box.find("img.buildimage").on('load', imageOnload)
.filter(function () {
//if the image is already loaded manually trigger the event
return this.complete;
})
.trigger('load');
});
function imageOnload(evt){
var img = $(evt.currentTarget),
width = img.width();
if (width >= 650) {
img.addClass("buildimage-large");
} else if (width < 500 && width > 101) {
img.addClass("buildimage-small");
}
// if image is less than X, its most likely a smiley
else if (width < 100) {
img.addClass("buildimage-smiley");
}
}
Then, you can just add this statment in your success callback:
$("#container #" +response.postid).on("load", imageOnload);

How can i know if all <img> loaded in div using jQuery

How can i know if all loaded in div using jQuery
i want to do this after load all img in #slider div
var imgHeight = $("#slider img").height();
alert(imgHeight);
You can use the load event
$('#slider img').load(function(){
var imgHeight = $(this).height();
alert(imgHeight);
});
if there are more than one image, and you only want to obtain the height after they have all loaded, try this code
var img = $('#slider img');
var length = img.length;
img.load(function(){
length--;
if(length === 0){
alert("All images loaded");
};
});
Well, I've tested the code, and it appears that the problem hasn't got anything to do with the code. When loading the page with the images already in the cache, this is what I get:
Strangely, this does not occur when I force the browser not to use the cache.
Try this:
Attach an onload event listener to each image in the slider.
In the listener:
Give the current image a custom attribute to mark it is 'ready'.
Check if all images are ready. If so, do your thing (i.e. alert(imageHeight))
untested:
(function(){
var slider=document.getElementById('slider'),
images=slider.getElementsByTagName('img'), image, i=-1;
while (image=images[i]) {
image.onload=function(){
this['data-ready']=true;
var image, i=-1;
while (image=images[i]) if (!image['data-ready']) return;
// all images are ready; do your thing here
// ...
}
}
}());

Categories