Execute resize function only if a certain condition is met - javascript

I am dynamically resizing some boxes, and this functionality is placed inside my Images module. It works well, but since these boxes are present only on one part of the website, it throws me an error that it can't read the height property of undefined, which is obvious because the bundled file fires the window.resize but does not find the boxes, which blocks my other functionalities/modules.
So my question would be - is there a way to fire this resize event only if there are elements on the page that meet the certain class/id's (for example .box-image)... with some kind of conditional statement?
Many thanks for all possible hints.
EDIT: It throws error two times, first time because of the height property in the constructor, since this sets the initial height just after the reload.
class Images {
constructor() {
//make boxes same size as images initally and on resize
var images = $('.box-image');
var imageHeight = images[0].height;
var boxes = $('.content-box');
$(boxes).css({'height': imageHeight + 'px'});
this.events();
}
events() {
$(window).resize(function() {
var images = $('.box-image');
var imageHeight = images[0].height;
var boxes = $('.content-box');
if(images.length > 0) {
$(boxes).each(function (i, element) {
$(element).css({'height': imageHeight + 'px'});
});
}
});
}
}

An easy check before using the variable:
if (images && images.length > 0) { .. }
class Images {
constructor() {
//make boxes same size as images initally and on resize
var images = $('.box-image');
if (images && images.length > 0) {
var imageHeight = images[0].height;
var boxes = $('.content-box');
$(boxes).css({
'height': imageHeight + 'px'
});
this.events();
}
}
events() {
$(window).resize(function() {
var images = $('.box-image');
if (images && images.length > 0) {
var imageHeight = images[0].height;
var boxes = $('.content-box');
$(boxes).each(function(i, element) {
$(element).css({
'height': imageHeight + 'px'
});
});
}
});
}
}

Bring your var imageHeight = images[0].height; into your if statement like this
class Images {
constructor() {
//make boxes same size as images initally and on resize
var images = $('.box-image');
var imageHeight = images[0].height;
var boxes = $('.content-box');
$(boxes).css({'height': imageHeight + 'px'});
this.events();
}
events() {
$(window).resize(function() {
var images = $('.box-image');
var boxes = $('.content-box');
if(boxes && images.length > 0) {
var imageHeight = images[0].height;
$(boxes).each(function (i, element) {
$(element).css({'height': imageHeight + 'px'});
});
}
});
}
}

I guess this only is your each loop not working...
I assume that you want to change the height of elements which has content-box class only if there is an element having box-image class inside it.
First, no need for $() around element in that loop...
element is a variable which holds a content-box element while the loop cycles throught the collection held by the boxes variable.
class Images {
constructor() {
// Make boxes same size as images initally and on resize
var images = $('.box-image');
var imageHeight = images.height();
var boxes = $('.content-box');
boxes.css({'height': imageHeight + 'px'});
this.events();
}
events() {
$(window).resize(function() {
var images = $('.box-image');
var boxes = $('.content-box');
// If there is at least one image in the page
if(images.length > 0) {
// Loop all content-box
boxes.each(function (i, element) {
// Check if it has a box-image child
var childImage = element.find("'.box-image'");
if( childImage.length > 0 ){
var imageHeight = childImage.height();
element.css({'height': imageHeight + 'px'});
}
});
}
});
}
}
And no need for $() around boxes too, since this is already a valid jQuery collection.
(You also did it in constructor()).

Related

Javascript Resize to reset variables

I'm trying to have a bunch of variables reset themselves on a resize (I'm just a little crazy like that. Yes, I know virtually no one will do it as their using the page). I want to be able to have the plugin that I created (hScroll) reset it's variables when the user resizes the page. I only want to declare them and set them within one line, so I tried using the window.variableName = ... but that didn't seem to work. Once again, all I want to be able to do is have to declare and set the variable within one line, and on resize, have the variables reestablish themselves, since a few are size dependent. As you can see, I have also tried the triggerHandler method as well, but it does not seem to be working.
(function($) {
$.fn.extend({
hScroll: function(options) {
var defaults = {
container: "nav",
sliderName: ".sliderName",
partContainer: ".beep"
};
var o = $.extend(defaults, options);
return this.each(function() {
// I want to set global variables and have them reset... START
var slider = $(o.container + " " + o.sliderName),
sliderWidth = slider.outerWidth(),
container = $(o.container),
containerWidth = container.outerWidth(),
containerInnerWidth = containerWidth - (2 * parseInt(container.css("padding-left"))),
sliderPieces = slider.children(o.partContainer),
numberOfPieces = sliderPieces.length,
containerWidth = $(o.container).width(),
piecesWidth = 0;
// set slide widths
if (containerInnerWidth > sliderWidth / numberOfPieces) {
piecesWidth = sliderWidth / numberOfPieces
} else {
piecesWidth = containerInnerWidth;
}
sliderPieces.width(piecesWidth);
// set gutter and how many pieces can be seen at once.
var wholePiecesSeen = Math.floor(containerInnerWidth / piecesWidth),
gutter = parseInt((containerInnerWidth - (wholePiecesSeen * piecesWidth)) / 2);
// END - I want this block to be reset when the window is resized.
var isContainerBigEnough = function() {
if (containerInnerWidth > sliderWidth) {
$(o.container).removeClass("tooBig");
} else {
$(o.container).addClass("tooBig");
}
}
isContainerBigEnough();
// arrow variables
$(o.container + " .previous").click(function() {
var addOn = 0,
newPosition = 0,
thisFarGone = parseInt(slider.css("left")),
moveThisFar = piecesWidth,
allTheWay = containerInnerWidth - sliderWidth;
// always make sure to center your tiles
if (thisFarGone == allTheWay) {
moveThisFar = moveThisFar - gutter;
console.log(moveThisFar);
console.log("in");
};
newPosition = -thisFarGone - moveThisFar;
//make sure it doesn't go too far
if (newPosition < 0) {
newPosition = 0;
}
newPosition = parseInt(newPosition); // - addOn);
slider.css({
"left": (-newPosition) + "px"
});
});
$(o.container + " .next").click(function() {
var addOn = 0,
newPosition = 0,
thisFarGone = parseInt(slider.css("left")),
moveThisFar = piecesWidth;
// always make sure to center your tiles
if (thisFarGone == 0 ||
thisFarGone == -0 ||
thisFarGone == undefined) {
moveThisFar = moveThisFar - gutter;
};
newPosition = moveThisFar - thisFarGone;
//make sure it doesn't go too far
if (newPosition > sliderWidth - containerInnerWidth) {
newPosition = sliderWidth - containerInnerWidth;
}
newPosition = parseInt(newPosition); // - addOn);
slider.css({
"left": (-newPosition) + "px"
});
});
$(window).resize(function() {
console.log("working");
$(o.container).triggerHandler("hScroll");
});
});
}
});
})(jQuery);
$(document).ready(function() {
$(".posts-timeline").hScroll({
container: ".posts-timeline",
sliderName: "#slider",
partContainer: ".post"
});
});
Something like this?
console.log("working");
$(o.container).hScroll("hScroll");
Maybe not exactly that, but if you want those variables to be reassigned, I'm guessing that would wind up being done somewhere in $(window).resize(function() {

I am creating multiple sliders in a page... but not getting the correct stop position if the number of slides are different from each other

I am creating multiple sliders in a page... but not getting the correct stop position if the number of slides are different from each other..
If I keep the number of slides same it works well..
But I need different number of slides in sliders...
$(document).ready(function(){
$('.myslider-wrapper').each(function(){
// thumbSlide
var countSlider = $('.thumbSlide').length;
if((".thumbSlide").length){
// Declare variables
var totalImages = $(".thumbSlide > li").length,
imageWidth = $(".thumbSlide > li:first").outerWidth(true),
totalWidth = imageWidth * totalImages,
visibleImages = Math.round($(".thumbSlide-wrap").width() / imageWidth),
visibleWidth = visibleImages * imageWidth,
stopPosition = (visibleWidth - totalWidth/countSlider);
$(".thumbSlide").width(totalWidth+10);
$(".thumbSlide-prev").click(function(){
var parentMove = $(this).parent().prev('.thumbSlide');
if(parentMove.position().left < 0 && !$(".thumbSlide").is(":animated")){
parentMove.animate({left : "+=" + imageWidth + "px"});
}
return false;
});
$(".thumbSlide-next").click(function(){
var parentMove = $(this).parent().prev('.thumbSlide');
if(parentMove.position().left > stopPosition && !$(".thumbSlide").is(":animated")){
parentMove.animate({left : "-=" + imageWidth + "px"});
}
return false;
});
}
});
});
here is jsFiddle URL:
http://jsfiddle.net/mufeedahmad/GLSqS/
You iterate through all sliders correctly by doing $('.myslider-wrapper').each(), but then you do some stuff with $('.thumbSlide') that should be $('.thumbSlide', this).
$('.thumbSlide') will select all elements on the page with that class, while $('.thumbSlide', this) within the each callback will only select the element in that particular wrapper.
Edit: fixed your jsfiddle with this solution: http://jsfiddle.net/GLSqS/1/

Jquery resizeable auto resize parent

I've got a couple of nested resizable div's that need to resize to accommodation the child size.
Everything works fine until i try to resize one of the outer div's (vertically) then it gets stuck.
Here's a fiddle.
$(function () {
$('.block').resizable();
$('.block').resize(resize_handler);
});
function checkChildren(object) {
$(object).children(".block").each(function (index, item) {
var itemH = $(item).position().top + $(item).height();
var itemW = $(item).position().left + $(item).width();
if ($(object).width() < itemW) {
$(item).width($(object).width());
checkChildren($(item));
}
if ($(object).height() < itemH) {
$(item).height($(object).height());
checkChildren($(item));
}
});
}
function checkParent(e) {
var object = $(e);
var par = object.parent();
var totalW = object.width() + object.position().left;
var totalH = object.height() + object.position().top;
if (totalH > par.height()) {
par.height(totalH);
checkParent(par);
}
if (totalW > par.width()) {
par.width(totalW);
checkParent(par);
}
}
function resize_handler(e, ui) {
e.stopPropagation();
var object = $(this);
var par = object.parent();
if (par.hasClass("block")) {
checkParent(object);
}
if (object.children('.block').length > 0) {
checkChildren(object);
}
}
Sure you've already thought of this but could you try limiting the resizeability of the parent div if its height is too close to the height of its child. Meaning when it is about to come in contact with the edge of a child then don't allow it to come any closer. Maybe maintain a buffer around the children of a few pixels which would force the user to adjust the child first before they could adjust the parent any smaller.
Just a thought.

Have font size change according to size of div

I have a resisable div with text inside. I want the text to scale as the div changes size.
Specifically, I want the text to have the largest possible font size that will make it fit inside the div.
Use FitText http://fittextjs.com/
I use this plugin that I made based on fitText.js, because fitText doesn't fit my needs, due to I don't know the length of the strings to resize, so the fix resize parameter of fitText don't work in all cases.
$.fn.adjustTextSize = function (set_max_size, min_size) {
min_size = min_size || 12; // if no value then set a default one
var string, width, line, initFontSize, returnFontSize, ratio;
return this.each(function() {
// Store the object
var $this = $(this);
var resizer = function () {
string = $this;
string.html('<span style="white-space: nowrap;">' + string.html() + '</span>');
width = string.width();
line = $(string.children('span'));
initFontSize = parseInt(string.css('font-size'));
ratio = width/line.width();
returnFontSize = initFontSize*ratio;
if (set_max_size && returnFontSize > initFontSize) {
returnFontSize = initFontSize;
}
if (min_size && returnFontSize < min_size) {
returnFontSize = min_size;
}
string.css('font-size',returnFontSize);
while (line.width() >= width) {
if (min_size && returnFontSize <= min_size) {
string.html(line.html());
return false;
}
string.css('font-size', --returnFontSize);
}
string.html(line.html());
}
// Call once to set.
resizer();
// Call on resize. Opera debounces their resize by default.
$(window).on('resize orientationchange', resizer);
});
};
$('.js-adjust-text').adjustTextSize(false, 12);
$('.js-adjust-text-limit').adjustTextSize(true, 30);
This plugin get two parameters:
set_max_size: boolean to limit maximum font size to its defined size in CSS
min_size: Integer number to limit minimum font size.
I hope it works for your case.
You can try like this:
If you want the height to adjust, try setting the height to auto
$("#sample").modal({
containerCss:{
backgroundColor:"#fff",
borderColor:"#0063dc",
height:450,
padding:0,
width:830
}
});
here is a little changed code above, because it is for getting width of container I made edit for heigh container adjustment.
$.fn.adjustTextSize = function (set_max_size, min_size) {
min_size = min_size || 12; // if no value then set a default one
var string, height, line, initFontSize, returnFontSize, ratio;
return this.each(function() {
// Store the object
var $this = $(this);
var resizer = function () {
string = $this;
string.html('<span>' + string.html() + '</span>');
height = string.height();
line = $(string.children('span'));
initFontSize = parseInt(string.css('font-size'));
ratio = height/line.height();
returnFontSize = (initFontSize*ratio) ;
if (set_max_size && returnFontSize > initFontSize) {
returnFontSize = initFontSize;
}
if (min_size && returnFontSize < min_size) {
returnFontSize = min_size;
}
string.css('font-size',returnFontSize);
while (line.height() >= height) {
if (min_size && returnFontSize <= min_size) {
string.html(line.html());
return false;
}
string.css('font-size', --returnFontSize);
}
string.html(line.html());
}
// Call once to set.
resizer();
// Call on resize. Opera debounces their resize by default.
$(window).on('resize orientationchange', resizer);
});
};
Hope it will useful

Javascript jQuery only shows Image element once in IE. FF works

I want to show a big Image when I press the small thumbnail. A simple Lightbox style script.
When I press the grey transparent overlay area around the image, the CSS and image is removed from view. This code is stripped down. Maybe missed something needed...
$(document).ready(function() {
$(".lightBobo").click(function(e) {
e.preventDefault(); // prevent to open link in new window
$(this).lightBobo();
});
});
jQuery.fn.lightBobo = function(e) {
if (e != undefined)
e.preventDefault();
return this.each(function() {
var img = new Image();
$(img).load(function() {
imgW = img.width;
imgH = img.height;
var overlay = $("<div />");
var container = $("<div />");
// Lots of css styling for <div> overlay and container image...
container.append(img); //add image to div
$("body").append(overlay); //add overlay to body
$("body").append(container); //add div to body
overlay.fadeIn("fast", function() {
container.show();
});
$(overlay).click(function() {
removeDivs();
});
function removeDivs() {
container.hide();
overlay.fadeOut("fast");
img = null;
container = null;
overlay = null;
openImgSrc = "";
}
});
});
}
The problem is IE(7) is not showing the image the second time I want to show it. I have to do a page reload to display the image again. It works in FF though.
When I use FireFox I can see in FireBug that the get appended to for each time I show the big image. And the "old" image get's display: none; After 20 times I show the big image, I have 40 elements of Overlay and Container(image).
I can't figure out how to rerun the lightBobo function when needed. So it workes in both IE and FF.
You should probably append the overlay and container just once when initialized, then just show/hide/append content when the user activates the modal.
Otherwise you need to do .remove() on each element ( = null is not enough ) when unloading, unless you want lots of dupes in the DOM.
I would do something like this:
(function($) {
var lightBobo = {
init: function() {
var self = this;
this.overlay = $('<div>').click(this.hide); // bind the click event just once
this.container = $('<div>');
// apply id's or styling
$(document.body).append(overlay,container);
}
hide: function(e) {
lightBobo.container.hide();
lightBobo.overlay.fadeOut('fast');
},
show: function() {
var img = new Image();
$(img).load(function() {
imgW = img.width;
imgH = img.height;
lightBobo.container.append(img); //add image to div
lightBobo.overlay.fadeIn("fast", function() {
lightBobo.container.show();
});
});
}
};
$(function() {
lightBobo.init(); // init the lightbox once
});
$.fn.lightBobo = function() {
return this.each(function() {
lightBoo.show.apply(this);
});
}
})(jQuery);
// bind the anchors here:
$(document).ready(function() {
$(".lightBobo").click(function(e) {
e.preventDefault(); // prevent to open link in new window
$(this).lightBobo();
});
});
I have found a solution. I changed lots of code. Specially the $(img).load(function() { ... } where I was having some problems. I dont really know WHY the load() function didnt want to kick the event more than one time. So I removed most code out of that function.
Remember the $(img).load(function() { ... } is for loading the image BEFORE finding its width and height. otherwise its 0.
$(document).ready(function() {
$(".lightBobo").click(function(e) {
if (e != undefined)
e.preventDefault();
$(this).lightBobo();
});
});
jQuery.fn.lightBobo = function(e) {
return this.each(function() {
var myClickedObj = $(this);
//check if we have a anchor or image tag
var src = "";
if (this.tagName.toLowerCase() == "a")
src = this.href.toLowerCase();
else if (this.tagName.toLowerCase() == "img")
src = this.src.toLowerCase();
else
return;
var winW = $(window).width();
var winH = $(window).height();
var docH = $(document).height();
if (docH < winH)
docH = winH;
//the semitransparant overlay over the whole page
var overlay = $("<div />")
.attr("class", "bobOverlay") //used as id for closing all overlays
.css("background", "#000")
.css("opacity", "0.8")
.css("display", "none")
.click(function() { hideAll(); })
$("body").append(overlay); //add overlay to body
var loadLeft = (winW / 2) - (100 / 2);
var loadTop = (winH / 2) - (20 / 2) + $(document).scrollTop();
overlay.fadeIn("fast");
//an element to hold our picture
var container = $("<div />");
container.attr("class", "bobOverlay");
container.hide();
var img = new Image();
$(img).load(function() {
var imgW = img.width;
var imgH = img.height;
container.append(this); //add the picture to the container
$("body").append(container); // add container to the body
container.fadeIn("fast"); //show container
})
.attr("src", src); //add the src to the image
function hideAll() {
$(".bobOverlay").fadeOut("fast");
}
function IsImage(filename) {
var ext = filename.split('.').pop().toLowerCase();
var allow = new Array("gif", "png", "jpg", "jpeg", "bmp");
if (jQuery.inArray(ext, allow) == -1) {
return false;
}
return true;
}
});
}
Sorry for the long code. And finding out the answer myself...

Categories

Resources