Jquery height() set using imagesloaded - javascript

I'm trying to set the position of a menu beneath a slider that is dynamically generating the height, so I've used imagesloaded to load my jquery last and all is well in every browser except safari where it retrieves the height of the slider set in the back-end and not the height of the image which is dynamically generated depending on page size. this is only occurring in safari....
Here is the javascript to position the menu:
$.browser.safari = ($.browser.webkit && !(/chrome/.test(navigator.userAgent.toLowerCase())));
if ($.browser.safari) {
$(window).load(function () {
var $container = $('.ls-wp-fullwidth-container');
$container.imagesLoaded(function () {
var height = $(".ls-wp-fullwidth-container").height() - 50;
$(".menu_wrap").css('top', height);
});
});
} else {
$(window).load(function () {
var $container = $('.ls-wp-fullwidth-container');
$container.imagesLoaded(function () {
var height = $(".ls-wp-fullwidth-helper").height();
$(".menu_wrap").css('top', height);
});
});
}
$(window).resize(function () {
var height = $(".ls-wp-fullwidth-container").height() + 40;
$(".menu_wrap").css('top', height);
});
The slider that is being used is anything slider I'm using a themeforest theme named cleanspace and running wordpress 3.5.1.
I've tried using $(window).bind("load",function(){ to load the jquery last and $.browser.safari = ($.browser.webkit && !(/chrome/.test(navigator.userAgent.toLowerCase())));
if ($.browser.safari) {
to detect the browser which works fine on pc but fails on mac, so I'm left with the first code pasted here and await any help with baited breath.
NOTE: the if statement here is un-needed if safari would load my jQuery after the slider images...

I have found a work around I'm guessing it's not the best anwser and would be happy to hear better suggestions, basically I've placed a timer on the function to load like so:
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
$(window).load(function() {
setTimeout(function(){
var $container = $('.ls-wp-fullwidth-helper');
$container.imagesLoaded( function() {
var height = $(".ls-wp-fullwidth-helper").height() ;
$(".menu_wrap").css('top', height);
});
}, 2000);
});
}
else {
$(window).load(function() {
var $container = $('.ls-wp-fullwidth-helper');
$container.imagesLoaded( function() {
var height = $(".ls-wp-fullwidth-helper").height();
$(".menu_wrap").css('top', height);
});
});
}
$(window).resize(function(){
var height = $(".ls-wp-fullwidth-helper").height() + 40;
$(".menu_wrap").css('top', height);
});

Related

Get the change of dimensions on resize using jQuery

For my web site I am using the following code:
$(window).resize(function (event) {
window.location.reload();
});
Unfortunately when using the site on a mobile device there are minute resize events that occur. I am wanting to put in a tolerance so that these minute changes do not fire this reload.For this I need to know the change in dimensions that occurred in the resize event. I have been looking at the event object however it is huge and ugly.
Thanks in advance :)
You could achieve this by tracking the original window dimensions and then comparing those dimensions with current dimensions (acquired during each resize event) to determine the amount of change.
The following shows how you could trigger a reload if the width changes by a certain total THRESHOLD amount:
var THRESHOLD = 50; // the threshold that must be exceeded to trigger reload
$(window).resize(function(e) {
var width = $(window).width();
// Record the starting window width that the comparison will
// be relative to
if(window.startWidth == undefined) {
window.startWidth = width;
}
// Calculate the total change since first resize event
var widthChange = Math.abs(width - window.startWidth);
// If change exceeds THRESHOLD, trigger reload
if(widthChange > THRESHOLD) {
window.location.reload();
}
})
Building on the helpful comments of JBDouble05 and the helpful answer by Dacre Denny I have made a final solution that fits my needs. Here it is to help others in the future hopefully.
var OGwidth = $(window).width();
var OGheight = $(window).height();
var threshold = 50;
$(window).resize(function (e) {
if (OGwidth < 768) {
var newWidth = $(window).width();
var newHeight = $(window).height();
var widthChange = Math.abs(OGwidth - newWidth);
var heightChange = Math.abs(OGheight - newHeight);
if (widthChange > threshold || widthChange > threshold) {
window.location.reload();
}
} else {
window.location.reload();
}
//reset for next resize
OGwidth = newWidth;
OGheight = newHeight;
})

jQuery dynamically set incremented height to elements

What I want to achieve:
for each ul.container -> find the greatest li height -> add 25px to it -> apply that new height to all li within the container.
I need the calculation to happen also on window resize.
The problem:
While this works at page load, when resizing the browser window, the height keeps incrementing by 25px at every loop. I can't seem to figure out what I am doing wrong.
My code:
function listHeight() {
$("ul.container").each(function () {
var listHeight = 0;
var newHeight = 0;
$("li", this).each(function () {
newHeight = $(this).height();
if (newHeight > listHeight) {
listHeight = newHeight;
}
});
$("li", this).height(listHeight += 25);
});
}
listHeight();
$(window).resize(function () {
listHeight();
});
JSFiddle: http://jsfiddle.net/upsidown/VtypM/
Thanks in advance!
The height increases because you set the height in the first run. After that the height remains the "max hight" + 25 and adds additional 25 to it.
To prevent that just reset the height of the element to auto.
function listHeight() {
$("ul.container").each(function () {
var listHeight = 0;
var newHeight = 0;
$("li", this).each(function () {
var el = $(this);
el.css('height', 'auto');
newHeight = el.height();
if (newHeight > listHeight) {
listHeight = newHeight;
}
});
$("li", this).height(listHeight += 25);
});
}
listHeight();
$(window).resize(function () {
listHeight();
});
For better performance I suggest that you debounce/throttle the function call.
you need to add
$("li", this).height("auto");
after
var listHeight = 0;
var newHeight = 0;
view Demo
I think you need to look at this thread.
jQuery - how to wait for the 'end' of 'resize' event and only then perform an action?
You need to call it at the end of the resize event.
Hope it helps!
You need to increment height only if newHeight > listHeight, I think.

Anyway to optimise this parallax script for better performance?

I have a parallax script that I am using to slow the background position of an element relative to the window scroll. It performs GREAT on my macbook pro but on slower computers it shudders more than I feel it needs to.
Here is the code below:
var bgobj = $('.paral');
$(window).scroll(function () {
onScroll(bgobj);
});
function onScroll(bgobj) {
var $window = $(window);
var yPos = ($window.scrollTop() / bgobj.data('speed'));
// Put together our final background position
var coords = yPos + 'px';
// Move the background
bgobj.css({ backgroundPositionY: coords });
}
So my question is, what optimisations can be made to the code to improve speed on lower machines?
Thank you
Have you considered throttling?
http://underscorejs.org/#throttle
http://underscorejs.org/#debounce
var bgobj = $('.paral');
var onScrollThrottled = _.throttle(onScroll, 100);
$(window).scroll(function () {
onScrollThrottled(bgobj);
});
function onScroll(bgobj) {
var $window = $(window);
var yPos = ($window.scrollTop() / bgobj.data('speed'));
// Put together our final background position
var coords = yPos + 'px';
// Move the background
bgobj.css({ backgroundPositionY: coords });
if (isScrolledIntoView($('#more-info'))) {
animateCircle();
}
}
Of course, instead of throttling/debouncing the entire onScroll function you can apply the optimisation to animateCirle or updating the background css
I see some minor improvements to be done. Nothing big:
//cache $window and speed
var $window = $(window);
var bgobj = $('.paral');
var speed = bgobj.data('speed')
$window.scroll(function () {
onScroll(bgobj);
});
function onScroll(bgobj) {
var yPos = ($window.scrollTop() / speed);
// Put together our final background position
//var coords = yPos + 'px'; // this is not needad as jQuery defaults to pixels if nothing is specified
// Move the background
bgobj.css({ backgroundPositionY: coords });
if (isScrolledIntoView($('#more-info'))) { // depending on what is inside this function, this might slow everything doen
animateCircle();
}

Container height based on every 2 images row

I´m working on this website
I´m doing the resize of vertical images using this script:
function Gallery(selector) {
this.add_module = function (type, image) {
var portrait_text = image.next('.portrait_text');
var container = $('<div />', {
'class': 'gallery_container'
}).append(image).append(portrait_text);
if (type == 'horizontal') {
var h_ar = image.attr('height') / image.attr('width');
var c_width = selector.width();
var c_height = selector.width() * h_ar
container.css({
'width': c_width,
'height': c_height
})
}
if (type == 'vertical') {
var c_width = v_width;
var c_height = v_height
container.css({
'width': Math.floor(v_width),
'height': v_height
})
}
container.css({
'float': 'left',
})
container.find('img').attr({
'width': '100%',
'height': '100%'
})
container.attr('ar', c_height / c_width)
container.appendTo(selector);
//container.children('img').fitToBox();
}
this.resized = function () {
//console.log(sel)
$('.gallery_container').each(function () {
if ($(this).attr('ar') >= 1) { // vertical
$(this).css({
'width': sel.width() / 2,
'height': sel.width() / 2 * $(this).attr('ar')
})
} else { // horizontal
$(this).css({
'width': sel.width(),
'height': sel.width() * $(this).attr('ar')
})
}
})
}
var _this = this;
var gutter = 0;
// start vars for counting on vertical images
var v_counter = 0;
var w_pxls = 0;
var h_pxls = 0;
var v_ar;
// iterates through images looking for verticals
selector.children('img').each(function () {
if (parseInt($(this).attr('width')) < parseInt($(this).attr('height'))) {
v_counter++;
h_pxls += $(this).attr('height');
w_pxls += $(this).attr('width');
v_ar = $(this).attr('height') / $(this).attr('width')
}
})
// calculates average ar for vertical images (anything outside from aspect ratio will be croped)
var h_avrg = Math.floor(h_pxls / v_counter);
var w_avrg = Math.floor(w_pxls / v_counter);
var v_width = Math.floor((selector.width()) / 2);
var v_height = v_width * v_ar;
var sel = selector;
selector.children('img').each(function () {
if (parseInt($(this).attr('width')) > parseInt($(this).attr('height'))) {
_this.add_module('horizontal', $(this));
} else {
_this.add_module('vertical', $(this));
}
})
$(window).bind('resize', _this.resized);
}
var gallery = new Gallery($('#gallery_images_inner'));
http://jsfiddle.net/mZ2Ks/
The problem I have is that the script makes all the container the same of height (depending on the last image on the page I think), so for example first images resizes in a bad way. If you look at the example, all 2 image rows have a height of 613px.
Is there any way how can I control each two images container to calculate it´s own height based on its images, it looks like right now it calculates the last image resize height and apply it to all other containers
Applying height: auto instead of 100% won´t work cause it will not make the images fit the height of the vertical container.
How can I fix the script?
yes, there is a easy way. but frist: your gallery-script calculates a average aspect ratio for all images inside. there is no simple way to change this behavior.
But you can do this simple workaround: put echt two images in their own gallery!
var gallery1 = new Gallery($('#gallery_images_inner1'));
var gallery2 = new Gallery($('#gallery_images_inner2'));
var gallery3 = new Gallery($('#gallery_images_inner3'));
See http://jsfiddle.net/mZ2Ks/2/ - i had to clean up your html code a little bit - you copied the "javascript affected" html code from (i assume) firebug, but you should have copied the plain html from source code direct (CTRL + U in firefox).

Mouse-over script for touch devices

I'm trying to use this image skimming script on my website, which I want to be iPhone and iPad compatible. The problem is it is based on mouse-over so it doesn't work on touch. Any way anyone could help me change the script so instead of hovering over the images you click and drag to skim through them? So it could work on touch devices? Thanks. (Example of the script: http://www.fourcornersbooks.co.uk )
(function($) {
$.fn.skim = function() {
return this.each(function() {
var container = $(this);
var numImgs = container.find("img").size();
var zoneWidth = container.width() / numImgs;
container.find("img").css("display", "none");
container.find("img:first").css("display", "block");
container.mousemove(function(e) {
var offset = container.offset();
x = e.pageX - offset.left;
var currentZone = Math.floor(x / zoneWidth);
$(this).find("img").css("display", "none");
$(this).find("img:eq(" + currentZone + ")").css("display", "block");
});
container.mouseout(function(){
$(this).find("img").css("display", "none");
$(this).find("img:first").css("display", "block");
});
});
}
})(jQuery);

Categories

Resources