jQuery.clone() an element, then add dynamic styling to it - javascript

Let's say I have an image, cat.jpg, and when clicked I want to clone it.
$('img.cat').on("click", function() {
$(this).clone().appendTo('#container');
});
Upon duplication, however, I want the new cat.jpg to appear as half the size of the original. And I want this to continue happening each time a new cat.jpg is clicked.
Any ideas on how to go about accomplishing this? Is it even possible to inject new styling/classes/parameters via .clone()?

It sounds like the following is what you're after:
// If all images are within #container, use $("#container") instead:
$(document).on("click", "img.cat", function () {
var original = $(this);
original.clone().css({
width: original.width() / 2,
height: original.height() / 2
}).appendTo("#container");
});
Fiddle: http://jsfiddle.net/G6XTz/
Of course, you may have wanted the newly added image to be half the size of the last cat image, rather than the cat image clicked:
Fiddle2: http://jsfiddle.net/G6XTz/1/
Caveat:
The width and height can only divide so far; eventually you'll run into some problems. Better check the result of division first, and make a decision to do something else when it makes sense.

Just setting the width to half seems to be enough with an img element, the height gets set automatically in proportion to the width:
$('#container').on('click','img.cat', function() {
$(this).clone()
.appendTo('#container')
.width(function(i,v) { return v/2;});
});
Demo: http://jsfiddle.net/Mr2x8/
But if you find you need to set the width and the height here's one way to do it:
$('#container').on('click','img.cat', function() {
var $this = $(this);
$this.clone()
.appendTo('#container')
.width($this.width()/2)
.height($this.height()/2);
});
Demo: http://jsfiddle.net/Mr2x8/1/

id do this:
$(this).clone().addClass('small').appendTo('#container');
this adds the css class small to the clone of this.

Create a new class with the specific new styling you want to get changed dynamicaly in your CSS file.
.newClass {
//example green outline
outline: solid thin green;
}
And then modify your script:
$('img.cat').on("click", function() {
$(this).clone().addClass('newClass').appendTo('#container');
});
EDIT :
If the only thing you want to change is the size of the img for lets say 10% each click then:
$('img.cat').on("click", function() {
var width = $(this).width() * 0.9;
var height = $(this).height() * 0.9;
$(this).clone().css({"width":width+"px", "height":height+"px"}).appendTo('#container');
});
The above code will produce the same image but 10% smaller than the image clicked .
If you want to click only the initial image then simply put the width and height variable outside the click function and update them inside for each click.
NOTE :
In the css() you add +"px" if initial width is in px else you add +"%" if it is in percentage.

Related

JS/jQuery fit all images inside div (without whitespace)

I have a div call it #container,
Inside this #container I have n amount of img tags call it images
n can be 2, 10, 40 and so on.
I am wondering how I can fit n amount of images inside a #container to close all white spaces stretch the images. Quality doesn't matter
This is what I tried until now:
var amount = $("#container > img").length;
var amount_w = amount*200; //200 width of 1 image
var amount_h = amount*130; //120 height image
var refH = $("#container").height();
var refW = $("#container").width();
var refRatio = refW/refH;
$("#container img").each(function(){
$(this).height((amount_h-130)-refH);
$(this).width((amount_w-230)-refW);
});
First of all, it IS possible to achieve what you need even while maintaining the aspect ratio of the images - however the row height will be calculated, but it is not a trivial task (well, at least not as trivial as a single line formula).
There is a jQuery plugin called jPictura which I have developed. I believe the plugin does exactly what you need.
Here is a working fiddle.
You can find the plugin source codes and documentation on GitHub.
Simple example how to use the plugin:
$(document).ready(function () {
$('#my-gallery').jpictura({
layout: { itemSpacing: 0, justifyLastRow: true, idealRowHeight: 200}
});
});
itemSpacing - amount of space between the images in pixels
justifyLastRow - if true, the images in last row will be stretched to take the full width of the row
idealRowHeight - The desired height of the rows in pixels. The plugin will do its best to arrange the items so the row heights are as close as possible to this value.
there are a lot more options documented on GitHub
Beside the JS stuff that calculates the correct widths and heights of the images, there is one more thing to be considered regarding the blank space between images. Images are by default inline-blocks which means they behave like words and words do have some white space inbetween, right? Make them display: block; float: left; or use the flex box layout to get rid of the blank space. The plugin uses float: left; by default.
I created something that might interest you
var container = $('#container');
var height = container.outerHeight();
var width = container.outerWidth();
function populate(n){
var rem_items = n;
var rows = Math.round(Math.sqrt(n));
var row_items = Math.ceil(n/rows);
for (var i=0; i<rows; i++){
// this prevents us from generating a lonely single box in a row
if( (rem_items%(rows-i))===0 ){
row_items = rem_items/(rows-i);
}
if(rem_items<row_items){
row_items = rem_items;
}
rem_items = rem_items-row_items;
for (var j=0; j<row_items; j++){
var img_height = height/rows;
var img_width = width/row_items;
var img_left = j*img_width;
var img_top = i*img_height;
var img = $('<div class="cell"></div>');
img.css({
width: img_width,
height: img_height,
left: img_left,
top: img_top
});
container.append(img);
}
}
}
populate(40);
https://jsfiddle.net/jLq4hgaa/1/
Basically, it calculates the "most balanced" distribution of the images horizontally and vertically.
It does what you're asking for in the plainest sense. It distributes images/containers inside a container evenly regardless of aspect ratio.
$(document).on("pageload",function(){
$('.container').addClass('stretch');
});
Then make a css element called "stretch" defining width:100%
Height:100% and if need be define layout, i.e relative

Toggle class and change size on an element using jQuery

I am trying to have a div change its properties on a click function. Some of the properties I am changing with a call to toggleClass() which is fine and works great. However I also want to resize the div based on the size of the viewport. In order to have access to those numbers I am changing the width and height with jQuery. This command looks like this:
$('.box').click( function() {
$(this).toggleClass('box--grow', 0);
$(this).css('width', w * .9);
$(this).css('height', h * .9);
});
EDIT I want the height and width to go back to 100%.
I tried using the toggle class but that caused the entire div to disappear, and this solution doesn't work because when I click the div again the class is removed but the height is the same.
I am looking for a way to toggle this or to get the viewport width within the css. I tried both approaches but couldn't get anything to what I am looking for.
why not using CSS VH and VW values?
CSS:
.my90Class{
width: 90vw;
height: 90vh;
}
JS:
$('.box').click( function() {
$(this).toggleClass("my90Class");
});
You need to get the window size first, and then put everything into combined .ready() and .resize() functions, to make it responsive.
function myfunction() {
var w = $(window).width();
var h = $(window).height();
$('.box').click(function () {
if ($(this).hasClass('box--grow')) {
$(this).removeClass('box--grow');
$(this).css({
'width': '',
'height': ''
});
} else {
$(this).addClass('box--grow');
$(this).css({
'width': w * .9,
'height': h * .9
});
}
});
}
$(document).ready(myfunction);
$(window).on('resize', myfunction);
jsfiddle
You can check for the class with:
$(this).hasClass('box--grow')
Then to remove the class:
$(this).removeClass('box--grow');
And to add it back again:
$(this).addClass('box--grow');
The end would look like this save the original width and height before the event so you can add it back again:
var oldwidth = $('.box').css('width');
var oldheight = $('.box').css('height');
$('.box').click( function() {
if($(this).hasClass('box--grow')) {
$(this).removeClass('box--grow');
$('.box').css('width', oldwidth);
$('.box').css('height', oldheight);
} else {
$(this).addClass('box--grow');
}
});
untested but it would probably work

How to get a JS function to execute itself

I have a background image (width = 2000px, height = 400px) sitting behind a div with width and height equal to 400px. My image is split into 5 blocks, all with width and height equal to 400px. I want my image to shift by 400px each time the function is called to emulate a GIF image.
var imageWidth = $("#imageScroll").width();
console.log(imageWidth);
var timer = setInterval(function(){ shiftImage() }, 250);
function shiftImage(){
$("#imageScroll").mouseover (function(){
$("#imageScroll").css({"background-position-x": (imageWidth)});
});
};
});
This is my jQuery code, and I have tried and failed on a lot of different code. imageScroll is the ID of the div that I want the image to be pushed through.
you have to define css of the image so that it repeats itself on the x-axis.
<style>
#imageScroll{
height: 400px;
width: 500px;
background-image: url('./background.jpg');
background-repeat: repeat-x;
}
</style>
then, at the bottom of the page, or in body onload, you should execute the following instructions.
intervalFunc = setInterval(shiftImage, 250);
function shiftImage(){
var currentBackgroundX = $('#imageScroll').css('background-position-x');
split = currentBackgroundX.split("%");
currentBackgroundX = split[0];
currentBackgroundX = parseInt(currentBackgroundX);
$('#imageScroll').css({"background-position-x": (currentBackgroundX + 25) + '%'});
}
I didn't give too much though about the positioning part actually, since that is a completely different subject. But what i'm trying to do here is, change the background-position-x by 25% every 250 miliseconds. You can change the inner workings of the shiftImage function.
If you want to stop the animation at any point, just run
clearInterval(intervalFunc);
Hope this helps
Edit: jsFiddle
Edit 2: edited fiddle link
Edit 3: edited fiddle link

Changing image widths after page had loaded if width is declared already? If width is undeclared, width will change but not if declared as I have

The trouble is that I need these images with generated IDs "cam_snap_XXX" to become a different width if they are dragged and dropped into this area. I can make the height change but NOT THE WIDTH because the width is designated to 20px if x==1. Never is the image height specified therefore I believe that is the reason it is changeable? Q: How can I make these image widths change from 20px to 100px if "dragged"?
while (cnt <= 100) {
cam_icon=document.getElementById('cam_snap_' + cnt);
cam_icon.style.visibility = 'hidden';
if (x==1) {
cam_icon.style.width = '20px';
cam_icon.style.visibility = 'visible';
}
cnt++;
}
The height changes from the following javascript...
//js for adding class "dragged" which gives new height and width image parameters
$('.droparea td.drop').droppable({
onDrag: function (e, source) {
$(this).addClass('dragged'); //Changes height correctly not width though.
}
}
And the css..
//css for attempting to change image width and height on drop
.dragged{
height: 100px; //Works because height stretches image height from ~20px to 100px.
width: 100px; //**Doesn't work and is useless because width remains 20px.**
}
Should I try removing the class before adding class 'dragged' to these images? Using removeClass()? Any ideas are welcome even if not the solution.
This part of javascript modifies your HTML
cam_icon.style.width = '20px';
cam_icon.style.visibility = 'visible';
to
<someTag id="cam_snap_x" style="width:20px;visibility:visible">
According to css rules inline style (inside an HTML element) has the highest priority. so you'll have to change attribute value to see changes in UI.
Solution 1: change your onDrag function like below.
$('.droparea td.drop').droppable({
onDrag: function (e, source) {
$(this).width(100).height(100); //This will change the style property
}
}
Solution 2: Use !important to prioritize value specified in class over inline style attribute
.dragged{
height: 100px;
width: 100px !important;
}

Hide a div at specfic height while using slidetoggle()

I have three divs and i am trying to show/hide div2 when we click on any div. So far i have succeeded in it but now i want to implement some animation while show.hide the div.
I tried a lot and read many solution but due to i am new to jQuery i cant do it. Here is my code that i tried before animation
http://jsfiddle.net/9Lw6T/119/
$(".more , .expander,.headingopen").click(function() {
var expanderDiv = $(this).parents(".content_item").find(".textContent");
if ($(expanderDiv).length > 0 && $(expanderDiv).hasClass("expander") ) {
$(expanderDiv).removeClass("expander");
var MoreDiv = $(this).parents(".content_item").find(".more");
$(MoreDiv).html("Mindre");
}
else {
console.log("addclass");
$(expanderDiv).addClass("expander new");
var MoreDiv = $(this).parents(".content_item").find(".more");
$(MoreDiv).html("More");
}
});
jQuery(document).ready(function() {
jQuery(".more , .expander,.headingopen").click(function() {
jQuery('.expander').slideToggle("slow");
});
});
After Animation or slidetoggle
http://jsfiddle.net/9Lw6T/123/
Is there any way to animate the divs and stop at certain height while slideup as before animation i have done it in my first try without animate. Slidedown needs auto hide and its working with this code.
Thanks
There is an issue when using jQuery animate going to auto so you have to do a little work around (see: JavaScript jQuery Animate to Auto Height)
// get the current height
var curHeight = $textArea.height();
// set set the css to auto height and get how tall it is
var autoHeight = $textArea.css('height', 'auto').height();
// set the css back to the original height, then animate to the new height
$textArea.height(curHeight).animate({height: autoHeight}, 1000);
Here it is all together
http://jsfiddle.net/9Lw6T/127/

Categories