Detect the Body's Height - javascript

I have an Add More Attachments function. Every time I click the button, one more attachment shows up, which causes the page getting longer. I write a syntax to detect the body's height after the attachments show up, but somehow it doesn't work. Please help.
Live Code
HTML
<input type="file" /></div><button id="addNew">Add</button>
<div class="attachField"></div>
JS
var i=0;
$('#addNew').click(
function()
{
if( i < 10)
{
i++;
$('.attachField').append( '<div class="attachFile"><input type="file" /></div>' );
}
$('body').on('load', function()
{
var bodyAfterClick = $(this).contents().height();
alert(bodyAfterClick);
$('body').height(bodyAfterClick);
});
}); //end click

Is this what you wanted?
Body automatically gets longer when you add element to it. It's default behaviour when the element's height is not set.
I can't read the documentation right now but it's obvious that this works only on page load. Please read documentation more properly.
$('body').on('load', function())

as per you code i understand that you need to find the height of body when you append the input
Made some changes to your code
JS Fiddle
var i = 0;
$('#addNew').click(
function () {
if (i < 10) {
i++;
$('.attachField').append('<div class="attachFile"><input type="file" /></div>');
a = $('body').height()
console.log(a)
alert(a)
}
}); //end click

First of all why are you explicitly setting height to the body by $('body').height(bodyAfterClick);?
If you have to detect body height, you can try this -
$(document).height() - $('body').offset().top;
Reference link -
jQuery $("body").height() returns undefined

Related

Previous and Next Scrolling to next post

I've been struggling with this all day.. I've got a couple of posts, each have a next and previous button. The idea is for each post and its next and previous buttons, to scroll the window to the next post or previous post. I have tried using the each() function and unfortunately, its tricky to get working.
This is the jQuery so far:
var scrollTo = function(element) {
$('html, body').animate({
scrollTop: element.offset().top
}, 100);
}
function prev_next_scrolling() {
var articles = $("article.post"),
counter = 0;
articles.each( function() {
var articles = $(this);
$('.next-btn', articles).click( function() {
scrollTo($('article.post').eq(counter + 1));
});
$('.prev-btn', articles).click( function() {
scrollTo($('article.post').eq(counter - 1));
});
counter++;
});
}
prev_next_scrolling();
And this is the HTML:
<article class="post">
<h2>Post Title</h2>
<p>Post description</p>
Previous
Next
</article>
Here is the jsfiddle link for you guys to have a looksie!
http://jsfiddle.net/casacoda/2zM3Q/
Any help will be much appreciated! Thanks in advance guys!
The problem with your code is that counter is defined in the scope of prev_next_scrolling(), so all the functions run by the each() method will use the very same instance of the variable. Each time you increase counter, that will happen for all places where it has been used.
You can fix that by introducing a variable local to the function that handles a specific element -- or actually, you don't have to because jQuery already gives you exacly that as an optional parameter in the each() callable. See http://api.jquery.com/each/
So here's the correct code (http://jsfiddle.net/2zM3Q/3/):
var scrollTo = function(element) {
$('html, body').animate({
scrollTop: element.offset().top
}, 100);
}
function prev_next_scrolling() {
var articles = $("article.post"),
counter = 0;
articles.each( function(index) {
var articles = $(this);
$('.next-btn', articles).click( function() {
scrollTo($('article.post').eq(index + 1));
});
$('.prev-btn', articles).click( function() {
scrollTo($('article.post').eq(index - 1));
});
counter++;
});
}
prev_next_scrolling();
There are still some problems: It doesn't check whether it already is the first/last post and if it's already at the end of the page it obviously won't scroll any further, creating the illusion of a "broken" link (because nothing seems to be happening after clicking it.)
I've updated the fiddle to address all your concerns in the comments
Updated Working Fiddle
I got it working without all your each code, just navigating the dom.
Let me know if you have questions about the Fiddle provided. Basically this takes advantage of your current structure being known, it finds the next ARTICLE using parent().next() and then finds that ARTICLEs h2. It then uses the H2s vertical offset position to scroll to it. Same for previous links but using parent().prev()
$(document).on('click', '.next-btn', function(){
// find the next anchor
var nextAnchor = $(this).closest('article').next().find('h2')
$('html,body').animate({scrollTop: nextAnchor.offset().top},'slow');
});
$(document).on('click', '.prev-btn', function(){
// find the previous anchor
var prevAnchor = $(this).closest('article').prev().find('h2')
$('html,body').animate({scrollTop: prevAnchor.offset().top},'slow');
});
One thing to note, if the H2 in question is already visible on the screen it will not scroll UP to anything, only if its off screen will it scroll UP to it. Scroll down will always move the screen if needed.

jQuery document ready buggyness with social sharing services

I have a strange issue that might have to do with jQuery document ready. Below is an html and script block that contains the usual social networking scripts. The Javascript block below displays the dd_outer div on the left edge of the body div, and when the browser window is shrunk, the div is faded out and the dd_footer div is faded in. The fadein and fadeout between the two divs works OK.
The problem is two fold: one issue is when the browser window is full width (1200px+), the Facebook script will not load and display consistently; it sometimes appears and sometimes doesn't, sometimes after a page reload and sometimes doesn't. (No browser or .htaccess caching is involved). Only the Facebook share fails to show consistently; all other services show OK.
The second problem that when the browser window is narrow - 650 px or so, when the dd_outer div is not displayed and the dd_footer div is - the footer div will not show on a page reload until the browser window is moved the smallest amount. Then the the div will display, Facebook share and all. For a mobile device, this is a problem because the browser window will be narrow to begin with and shouldn't need to be "nudged" to make the dd_footer div display.
This problem may have come into play because I have adapted this code from a WordPress plugin that used options to set the position of the dd_outer div and scroll height. That's the reason for the variables above the document ready call.
Is this the issue with what seems to be a document ready issue?
How can the variables be integrated into the script itself? It doesn't matter if they are hardcoded; I can change them when needed.
I'd throw this in a jsfiddle to demo but the divs won't realistically float with the window resizing.
I haven't included the CSS for clarity.
This is the html and social script block:
<div class='dd_outer'><div class='dd_inner'><div id='dd_ajax_float'>
<div class="sbutton"><script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script><fb:like layout="box_count" show_faces="false" font=""></fb:like></div>
<div class="sbutton">
Tweet<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<div class="sbutton"><script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script><g:plusone size="tall"></g:plusone></div>
<div class="sbutton"><script src="http://platform.linkedin.com/in.js" type="text/javascript"></script>
<script type="IN/Share" data-counter="top"></script></div>
</div></div></div>
In the footer is <div id="dd_footer">that contains the same social scripts as above</div> and are faded in and out by the script below:
This is the jQuery that positions the dd_outer social services to the left and fades it out and fades in the dd_footer div.
<script type="text/javascript">
var dd_top = 0;
var dd_left = 0;
var dd_offset_from_content = 70; var dd_top_offset_from_content = 10;
jQuery(document).ready(function(){
var $floating_bar = jQuery('#dd_ajax_float');
var $dd_start = jQuery('#dd_start');
var $dd_end = jQuery('#dd_end');
var $dd_outer = jQuery('.dd_outer');
// first, move the floating bar out of the content to avoid position: relative issues
$dd_outer.appendTo('body');
dd_top = parseInt($dd_start.offset().top) + dd_top_offset_from_content;
if($dd_end.length){
dd_end = parseInt($dd_end.offset().top);
}
dd_left = -(dd_offset_from_content + 55);
dd_adjust_inner_width();
dd_position_floating_bar(dd_top, dd_left);
$floating_bar.fadeIn('slow');
if($floating_bar.length > 0){
var pullX = $floating_bar.css('margin-left');
jQuery(window).scroll(function () {
var scroll_from_top = jQuery(window).scrollTop() + 30;
var is_fixed = $dd_outer.css('position') == 'fixed';
if($dd_end.length){
var dd_ajax_float_bottom = dd_end - ($floating_bar.height() + 30);
}
if($floating_bar.length > 0)
{
if(scroll_from_top > dd_ajax_float_bottom && $dd_end.length){
dd_position_floating_bar(dd_ajax_float_bottom, dd_left);
$dd_outer.css('position', 'absolute');
}
else if ( scroll_from_top > dd_top && !is_fixed )
{
dd_position_floating_bar(30, dd_left);
$dd_outer.css('position', 'fixed');
}
else if ( scroll_from_top < dd_top && is_fixed )
{
dd_position_floating_bar(dd_top, dd_left);
$dd_outer.css('position', 'absolute');
}
}
});
}
});
jQuery(window).resize(function() {
dd_adjust_inner_width();
});
var dd_is_hidden = false;
var dd_resize_timer;
function dd_adjust_inner_width() {
var $dd_inner = jQuery('.dd_inner');
var $dd_floating_bar = jQuery('#dd_ajax_float')
var width = parseInt(jQuery(window).width() - (jQuery('#dd_start').offset().left * 2));
$dd_inner.width(width);
var dd_should_be_hidden = (((jQuery(window).width() - width)/2) < -dd_left);
var dd_is_hidden = $dd_floating_bar.is(':hidden');
if(dd_should_be_hidden && !dd_is_hidden)
{
clearTimeout(dd_resize_timer);
dd_resize_timer = setTimeout(function(){ jQuery('#dd_ajax_float').fadeOut(); }, -dd_left);
jQuery('#dd_footer').fadeIn();
}
else if(!dd_should_be_hidden && dd_is_hidden)
{
clearTimeout(dd_resize_timer);
dd_resize_timer = setTimeout(function(){ jQuery('#dd_ajax_float').fadeIn(); }, -dd_left);
jQuery('#dd_footer').fadeOut();
}
}
function dd_position_floating_bar(top, left, position) {
var $floating_bar = jQuery('#dd_ajax_float');
if(top == undefined) top = 0 + dd_top_offset_from_content;;
if(left == undefined) left = 0;
if(position == undefined) position = 'absolute';
$floating_bar.css({
position: position,
top: top + 'px',
left: left + 'px'
});
}
</script>
jQuery .ready() does not wait for iframes and other external media to load. These social buttons tend to work by inserting an iframe. The load event does wait for iframes etc, so you could try using that event instead, i.e.
jQuery(window).load(function () {
/* put the code you had inside .ready() here */
});
The problem comes with your idea: $(document).ready() fires when the DOM is ready, not when all scripts are ready!
an idea would be to search for trigger of that social-APIs you are using or just delay your calculations (e.g. via setTimeout).
Keep in mind that they are asyncron, even if you specify "async" on the script-tag to be false, you still dont know when they will activate or are finished.
I suggest to use the standard DOM event window.onload if you want to make sure that all the external assets, scripts, images, etc. are loaded first before you do something:
window.onload = function () {
// your script that needs to run after all the external assets are loaded
}
Reference: https://developer.mozilla.org/en-US/docs/DOM/window.onload
I just ran into similar problems with the facebook script... I just used the integration in the HEAD-section with javascript and added an "asynchronous"-attribute to the javascript-embedding script which then fires an asynchronous "heeey, facebook is ready now, too"-event to my jQuery-eventqueue...
I can't help you in detail, because I don't totally understand what you WANT to do and would reorganize the whole code A LOT... so - contact me private (email/skype) or try figuring out... I used that lines of code: pastie.org/private/9m4b9eet1dzzkl6duqpkrg

jQuery event listener for fully loaded DOM with dynamic content

I'm trying to use jQuery script to align height of two divs. Everything works fine until I have some dynamic content in one of divs.
When I hardcode some static content in one of divs like:
<br>asd<br>asd<br> x 20
both divs has the same height property, but when I load some data from DB to one of divs, they are different.
I guess that the problem is in .ready() listener. Documentation says that it fires when DOM is fully loaded but it looks like it's not the truth.
My question is: what kind of listener or other 'trick' should I use? I think that jquery/javascript solution is cleaner than messing with css and I would like to have this kind of solution.
Thanks in advance.
jquery script:
$(document).ready(function(){
var difference = $("#layout-navigation-wrapper").height() - $("#layout-content-wrapper").height();
if(difference<0)
{
var height = $("#layout-content-wrapper").height() -1;
$("#layout-navigation-wrapper").height(height);
}
else if(difference >= 0)
{
var height = $("#layout-navigation-wrapper").height() -2;
$("#layout-content-wrapper").height(height);
}
});
jquery in the base work with event document.ready is means when all DOM is ready until here make the jquery code. is for don't have a option to render jquery code without render jquery library
if you want to add event just when all the dom is loaded include content and images you need to do this
$(document).ready(function(){
$(window).load(function(){
var difference = $("#layout-navigation-wrapper").height() - $("#layout-content-wrapper").height();
if(difference<0)
{
var height = $("#layout-content-wrapper").height() -1;
$("#layout-navigation-wrapper").height(height);
}
else if(difference >= 0)
{
var height = $("#layout-navigation-wrapper").height() -2;
$("#layout-content-wrapper").height(height);
}
});
});
You can use window.onload to execute a script once a web page has completely loaded all content including images, script files, CSS files, etc.
window.onload = function() {
var difference = $("#layout-navigation-wrapper").height() - $("#layout-content-wrapper").height();
if(difference<0)
{
var height = $("#layout-content-wrapper").height() -1;
$("#layout-navigation-wrapper").height(height);
}
else if(difference >= 0)
{
var height = $("#layout-navigation-wrapper").height() -2;
$("#layout-content-wrapper").height(height);
}
};

Javascript taking too long to load

The javascript of the div "intro" is loading at last. It's taking too long to load as the web page loads the bg image first and then loads the java script. Is there a way i can display "loading please wait" message in that "intro" div until it completely loads. I just want that the intro should load first.
Javascript code:
var tl = new Array(
"=======================",
" Welcome user, ",
" ###########################################"
);
var speed = 50;
var index = 0;
text_pos = 0;
var str_length = tl[0].length;
var contents, row;
function type_text() {
contents = '';
row = Math.max(0, index - 20);
while (row < index)
contents += tl[row++] + '\r\n';
document.forms[0].elements[0].value = contents + tl[index].substring(0, text_pos) + "_";
if (text_pos++ == str_length) {
text_pos = 0;
index++;
if (index != tl.length) {
str_length = tl[index].length;
setTimeout("type_text()", 500);
}
}
else setTimeout("type_text()", speed);
}
This is the script and its basically typing letter by letter in a text area in the div "intro". The problem is that it loads at last when the whole page has loaded. It starts printing the text after like 15 seconds or so.
There are "domready" events you can listen to on the document but seems that's not cross-browser.
Eg: Mozilla
document.addEventListener("DOMContentLoaded", methodName, false)
A better option is to use jQuery's .ready() event. They handle all cross-browser implementations.
Eg:
$(document).ready(function(){
//execute code here
});
//Shorthand
$(function(){
//...
});
See this related question for more on domready.
Load a page with the empty intro div, run the script with "loading please wait" then trigger an ajax request to load the rest of the page and update the page on onComplete event from the ajax request
Using jQuery
$(document).ready(function() {
// update div here
});
http://api.jquery.com/ready/
Or you could do that with
window.onload= (function() {
// update div here
};
You can use jquery for this by wrapping the content in a div tag and then another div that holds a loading image, something to this effect:
$(document).ready(function () {
$('#loading').show();
$('#divShowMeLater').load(function () {
$('#loading').hide();
$('#divShowMeLater').show();
});
})
Assume divShowMeLater is the div that contains all the content being loaded. The markup would look similiar to this:
<div id="divShowMeLater" style="margin-left:auto;margin-right:auto;text-align:center;" >
<div id="loading">Page loading...
<img src="images/ajax-loader.gif" alt="loading page..." />
</div>
</div>

JavaScript Timed Image Swap Need Help

So in my script I have...
<script type="text/javascript">
var images = new Array();
var numImages = 3;
var index = 0;
function setupSwapper() {
for (i = 0; i < numImages; i++) {
images[i] = new Image(266, 217);
images[i].src = "images/image" + i + ".png";
}
setTimeout("swapImage()", 5000);
}
function swapImage() {
if (index >= numImages) {
index = 0;
}
document.getElementById('myImage').src = images[index].src
index++;
setTimeout("swapImage()", 5000);
}
</script>
And then I have <body onload="setupSwapper()"> to setup the body.
and <img width=266 height=217 id="myImage" name="myImage" src="images/image0.png"></img> elsewhere in my document.
Only the initial image (image0.png) is showing up. I'm probably blind from having looked at this so long. The images are not swapping.
Use FireBug or a similar tool for debugging what's going on:
Does the img DOM element in fact gets its src changed ?
Do you see any network activity trying to load the images ? does it succeed ?
Set up breakpoints in your code and see what happens in the debugger
BTW - You can use setInterval instead of setTimeout - it sets a repeating timer
You're missing the () in the definition of "setupSwapper".
Also it's setTimeout, not setTimeOut.
Finally, get rid of the "type" attribute on your <script> tag.
You might want to start "index" at 1 instead of 0.
The way to go:
setTimeout(swapImage, 5000);
[FORGET] the type attribute has nothing to do with it
[FORGET] the index has nothing to do with it
[OPTIONAL] remove "name" attribute from the image (useless)
[OPTIONAL] close image tags like <img />
Note: 2-5 is about correctness. Only the first one is important to get it work.
Get Firebug, use it's debugger to put breakpoints inside swapImage to see if it is hit after the timeout. Another way is to use the console.* apis to see what's happening(e.g. console.log).

Categories