I have a div that is being created in one of six locations (columns) and I then want these newly created divs (.letter-block). It should create a new block each second and these blocks need to "fall" to the bottom of the container column div (or stop at the top of last block in that column so as to get the effect the blocks are stacking on top of each other, similar to Tetris). I can get the blocks to create but once created, they don't "fall" to the bottom of the container div.
$(document).ready(function(){
setInterval(newLetter, 1000)
function newLetter(){
var $randCol = $("#col" + (Math.floor(Math.random()*6) + 1));
$randCol.prepend("<div class='letter-block'></div>").animate({'bottom':'0'}, 500);
};
});
Your code:
var $randCol = $("#col" + (Math.floor(Math.random()*6) + 1));
$randCol.prepend("<div class='letter-block'></div>").animate({'bottom':'0'}, 500);
The element that is selected here is one of your six columns. You prepend the new <div>, but the column is still what is selected, so you are trying to animate the column instead of the new <div>. Then you need to calculate how many blocks you are sitting on top of. Count the number of blocks in the column and then multiply that by their height, that is you new bottom position. Try this code:
$(document).ready(function(){
setInterval(newLetter, 1000);
function newLetter(){
var $randCol = $("#col" + (Math.floor(Math.random()*6) + 1));
var $newDiv = $("<div class='letter-block'></div>");
$randCol.prepend($newDiv);
$(document).ready(function(){
var $oldBlocks = $randCol.find('.letter-block');
var yPos = '' + ($oldBlocks.length * $oldBlocks.first().outerHeight());
$newDiv.animate({
'bottom': yPos
}, 500);
});
};
});
Make sure that the new div is position: absolute or position: relative (probably absolute in your case) or directional properties like bottom won't work on it. CSS:
.letter-block {
position: absolute;
// other CSS
}
Related
I want to get the position/offset of a table cell and then using this data I want to append and position a new element in the exact same position.
The code to achieve this is as follows:
function addBlock()
{
// get the cell position
var cellPosition = $('.item').position(),
cellPositionTop = cellPosition.top,
cellPositionLeft = cellPosition.left;
// append the overlay
var blockOverlay = $('<div class="blockOverlay"></div>').appendTo('.container').hide();
// set the overlay width and height to the same as the cell
blockOverlay.css({
'background-color':'blue',
'width': $('.item').outerWidth(),
'height': $('.item').outerHeight()
});
// position the overlay in the same place as the cell
blockOverlay.css({
'position': 'absolute',
'top': cellPositionTop,
'left': cellPositionLeft
});
// show the overlay
blockOverlay.show();
}
The table containing the cell is quite big and sits inside an overflowing element meaning that the table cell may be offscreen. If the above code is run without scrolling then it works fine, however if I scroll and then run it, the offset is incorrect. This is because even though I am using position() and not offset() it is getting the cell position relative to its parent (.container) at the time of calling the function, rather that its position regardless of the scroll position.
How can I solve this?
Here is a fiddle that shows the problem: https://jsfiddle.net/25e6qmnh/
Try clicking the button at various scroll positions and you will see that blue box only ever overlays the red cell when at the start position. It should ALWAYS overlay the red cell regardless of the scroll position.
You need to add $('.container').scrollLeft() to your cellPositionLeft, so the new line will look like this:
cellPositionLeft = cellPosition.left + $('.container').scrollLeft();
Your are not calculating the position with the scroll width, so you need to add it. You will also need to do the same with scrollTop(), but that will be left for you.
Here is a working example: https://jsfiddle.net/qorpucwq/
You can initialize the value of the element .item once and then it works fine.
function addBlock()
{
// get the cell position
var
cellPositionTop = cellPosition.top,
cellPositionLeft = cellPosition.left;
// append the overlay
var blockOverlay = $('<div class="blockOverlay"></div>').appendTo('.container').hide();
// set the overlay width and height to the same as the cell
blockOverlay.css({
'background-color':'blue',
'width': $('.item').outerWidth(),
'height': $('.item').outerHeight()
});
// position the overlay in the same place as the cell
blockOverlay.css({
'position': 'absolute',
'top': cellPositionTop,
'left': cellPositionLeft
});
// show the overlay
blockOverlay.show();
}
var cellPosition;
$(document).ready(function(){
cellPosition = $('.item').position();
$('.clickme').on('click', function(e){
e.preventDefault();
addBlock();
});
});
Here is the working fiddle.
I'd like opinions on whether or not Javascript is a still a viable and relatively effective method of producing fluid website layouts. I know that it is possible to create fluid layouts with Javascript, but relative to other methods (e.g. CSS3/HTML5) how does it stand up in terms of performance and complexity? The function below represents what I mean. In the function, javascript is being used to find the dimensions of various elements and place other elements accordingly. To see it working, follow this link.
function onPageResize() {
//center the header
var headerWidth = document.getElementById('header').offsetWidth; //find the width of the div 'header'
var insideHeaderWidth = (document.getElementsByClassName('header')[0].offsetWidth + document.getElementsByClassName('header')[1].offsetWidth + document.getElementById('logoHeader').offsetWidth); //find the combined width of all elements located within the parent element 'header'
document.getElementsByClassName('header')[0].style.marginLeft = ((headerWidth - insideHeaderWidth) / 2) + "px"; //set the margin-left of the first element inside of the 'header' div
/////////////////////////////////////////////////////////////////
//justify alignment of textboxes
var subtitleWidth = document.getElementsByClassName('subtitle'); //assign the properties of all elements in the class 'subtitle' to a new array 'subtitleWidth'
var inputForm = document.getElementsByClassName('inputForm'); //assign the properties of all elements in the class 'inputForm' to a new array 'inputForm'
for (i = 0; i < inputForm.length; i++) { //for every element in the array 'inputForm' set the margin-left to dynamically place the input forms relative to eachother
inputForm[i].style.marginLeft = (subtitleWidth[4].offsetWidth - subtitleWidth[i].offsetWidth) + "px";
}
/////////////////////////////////////////////////////////////////
//place footer on absolute bottom of page
if (window.innerHeight >= 910) { //when the page is larger than '910px' execute the following
var totalHeight = 0; //initialize a new variable 'totalHeight' which will eventually be used to calulate the total height of all elements in the window
var bodyBlockHeight = document.getElementsByClassName('bodyBlock'); //assign the properties of all elements in the class 'bodyBlock' to a new array 'bodyBlockHeight'
for (i = 0; i < bodyBlockHeight.length; i++) { //for every instance of bodyBlockHeight in the array, add the height of that element into the 'totalHeight'
totalHeight += bodyBlockHeight[i].offsetHeight;
}
totalHeight += document.getElementById('header').offsetHeight; //finally, to add the height of the only element that has yet to be quantified, include the height of the element 'header' into the 'totalHeight'
/*Set the margin-top of the element 'footer' to the result of subtracting the combined heights of all elements in the window from the height of the window.
This will cause the footer to always be at the absolute bottom of the page, despite whether or not content actually exists there. */
document.getElementById('footer').style.marginTop = (window.innerHeight - totalHeight) - document.getElementById('footer').offsetHeight + "px";
} else {
//if the page height is larger than 910px (approx the height of all elements combined), then simply place the footer 20px below the last element in the body
document.getElementById('footer').style.marginTop = "20px"
}
/////////////////////////////////////////////////////////////////
}
Again, the result of the above function can be viewed at this link.
Thank you to any and all who offer their opinions!
You should be using CSS rather than JavaScript because that is what CSS is designed to do. If you want a fluid layout play around with using percentage widths, floats and media queries.
Here is a link to a JSFiddle http://jsfiddle.net/9NYcn/11/ i put together with what i would like to do, but i need to do this with pure css.
function expand(){
var sect = document.getElementById("sect");
var body = document.getElementById("main");
var panes = document.getElementById("panes");
var newHeight = 40 + "px";
var newHeight2 = 120 + "px";
var topVal = 120 + "px";
sect.style.display = "block";
sect.style.height = newHeight;
body.style.height = newHeight2;
panes.style.top = topVal;
}
In the above function i had to set the "top" property of panes in order to get this to work. i need to get it so that the panes section will work like it currently does without using javascript to change the "top" property of "panes". When the user clicks the "expand" button the div with the class "body" will expand and not stick behind or overlap the "panes" div.
I know im doing a terrible job explaining i apologize for that.
Remove the absolute positioning of .panes: http://jsfiddle.net/rHTM8/
It will make it naturally flow after the middle div.
I create one div#sresult_container dynamically and append no of div to that div. and all appended div have different text. so i can retrieve the width of div#sresult_container but i try to that increase the width of div#sresult_container 10px before it display on the view port. how can i do this plese help me?
my code is below:
var $sresult_container = $('<div id="sresult_container"></div>');
AND after that i append the some divs as children of div#sresult_container.
and append to body.
$('body').append($sresult_container);
var Setwidth = $('#sresult_container').outerWidth() + 10;
$('#sresult_container').css('width',Setwidth + 'px');
so here first load original width after that load the modified width. so how can do directly load the modified width.
First of all #sresult_container must have a pre-defined width.
#sresult_container {
width: 100px;
}
$('<div id="sresult_container">text</div>').appendTo('body');
$('#sresult_container').css('width', function () {
return ($(this).outerWidth(true) + 10) + 'px';
});
http://jsfiddle.net/xBZT7/14/
http://jsfiddle.net/xBZT7/15/
function scrollContent(){
var div = $('#scrolling-content'),
ul = $('ul.image'),
// unordered list's left margin
ulPadding = 0;
//Get menu width
var divWidth = div.width();
//Remove scrollbars
div.css({overflow: 'hidden'});
//Find last image container
var lastLi = ul.find('li:last-child');
//When user move mouse over menu
div.mousemove(function(e){
//As images are loaded ul width increases,
//so we recalculate it each time
var ulWidth = lastLi[0].offsetLeft + lastLi.outerWidth() + ulPadding;
var left = (e.pageX - div.offset().left) * (ulWidth-divWidth) / divWidth;
div.scrollLeft(left);
});
}
This is how I scroll my image list. The problem is that #scrolling-content element's size is dynamic. It changes on window resize. Here;
$(window).resize(function() {
$("#scrolling-content").css("width",$(window).width() + "px");
$("#scrolling-content").css("height",($(window).height()-400) + "px");
});
So it has to recalculate the left value when user changes windows size. How sould I change script to do that? Recalling scrollContent() function with window.resize function is a noob solution I guess. And it creates conflict for IE.
You could set the width on resize and make your function call the variable like so. This method turns your function into a js object and the window update resets the width var inside that object. Course now you call the function like this: scrollContent.scroll();
var scrollContent = {
width: 0,
scroll:function(){
var div = $('#scrolling-content'),
ul = $('ul.image'),
// unordered list's left margin
ulPadding = 0;
//Get menu width
scrollContent.width = div.width();
//Remove scrollbars
div.css({overflow: 'hidden'});
//Find last image container
var lastLi = ul.find('li:last-child');
//When user move mouse over menu
div.mousemove(function(e){
//As images are loaded ul width increases,
//so we recalculate it each time
var left = (e.pageX - div.offset().left) * (ulWidth-scrollContent.width) / scrollContent.width;
div.scrollLeft(left);
});
}
};
$(window).resize(function() {
$("#scrolling-content").css("width",$(window).width() + "px");
$("#scrolling-content").css("height",($(window).height()-400) + "px");
scrollContent.width = $(window).width();
});
You can also just declare a standard js var and use that to keep things simple. I just prefer working with js objects to eliminate possible var interference.