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
Related
Chat does not scroll to bottom after jquery load method
My chat works by load new messages inside a scrolling div with jquery load method but div do not scroll to bottom when new messages are loaded, also I can't run out.scrollTop = out.scrollHeight; with the div load because as it loads every second when user click scroll to older messages it just make the scroll control flash all the time.
I am using this example of this fiddle
http://jsfiddle.net/dotnetCarpenter/KpM5j/
It all looks to work fine but it's not working when I use with jquery .load() method
my index.php
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.0/jquery.min.js"></script>
<script>
setInterval(
function() {
$('#out').load('load_chat.php');
var messageBody = document.querySelector('#out');
out.scrollTop = out.scrollHeight - out.clientHeight;
}, 3000);
</script>
<script>
var out = document.getElementById("out");
var c = 0;
var add = setInterval(function() {
// allow 1px inaccuracy by adding 1
var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;
console.log(out.scrollHeight - out.clientHeight, out.scrollTop + 1);
var newElement = document.createElement("div");
newElement.innerHTML = c++;
out.appendChild(newElement);
// scroll to bottom if isScrolledToBotto
if (isScrolledToBottom)
out.scrollTop = out.scrollHeight - out.clientHeight;
}, 1000);
</script>
<div id="out" style="overflow-y: scroll; height:80px;"></div>
I need to load the load_chat.php and also keep the page scrolling to the bottom
I can't use
var out = document.getElementById('out');
out.scrollTop = out.scrollHeight;
inside the load by Interval function, because it makes scrolling very weird, can someone help?
PLEASE VIEW SOURCE CODE ON BOTH PAGES.
On this page: _p1.html It is "page 1" Use the scroll bar on the right side of the browser to scroll all the way down to bottom of page. "page 2" will appear. I am using infinite scroll js.
I am also using scroll to anchor point with easing. Go back to top of the page again: _p1.html Click on "scroll down to item A" It scrolls down to middle of page with easing. Now, scroll down even more. Page 2 loads. Great. Now, click on "scroll down to item B" Item B just jumps to the middle page when it supposed to scroll with easing.
What is wrong? How do I fix this?
If you go directly to page 2 here: _p2.html Click on item B. You will see that easing works. BUT when on page 1 AND infinite js, the easing scroll does not work.
What is wrong? How do I fix this?
The scroll to js is fired off at page load and is not running again when new content is loaded into the page. Therefore the scroll effect will not work on any additional content loaded into the page (page2, page3, and so on). we need to find a way to re-trigger the javascript when new content is introduced and loaded into the page.
You can attach the event handler to a parent, in this case I've used $(document) but to avoid excess overhead use the closest parent, then tell jQuery to only bubble-up the event to '.page-scroll'. This way if any new elements are added to the document which have the class page-scroll this event will be attached to them as well.
$(function() {
$(document).on('click', '.page-scroll', function(e) {
e.preventDefault();
var $anchor = $(e.target);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 2500, 'easeInOutExpo');
});
});
EDIT
To make this work in your situation where the script may be included more than once, you have to make sure to only load jQuery, bootstrap and jasny once, then wrap the rest of the script in a window.onload event handler. as the window only loads once, if the script is included after the window is loaded it will not be executed.
I've also reduced the included jquery easings to only include easeInOutExpo which is the easing you are using in your function.
Replace all of the scripts on each page with the following script.
<script>
if (typeof jQuery == 'undefined') {
var newJQuery = document.createElement('script');
newJQuery.type = 'text/javascript';
newJQuery.src = 'https://code.jquery.com/jquery-2.1.1.min.js';
document.body.appendChild(newJQuery);
window.jQueryInterval = window.setInterval(function(){
if(typeof jQuery != 'undefined') {
window.clearInterval(window.jQueryInterval);
var newBootstrap = document.createElement('script');
newBootstrap.type = 'text/javascript';
newBootstrap.src = 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js';
document.body.appendChild(newBootstrap);
var newJasny = document.createElement('script');
newJasny.type = 'text/javascript';
newJasny.src = 'https://cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/js/jasny-bootstrap.min.js';
document.body.appendChild(newJasny);
/******************************************
Infinite jQuery Scroll
#author Fabio Mangolini
http://www.responsivewebmobile.com
******************************************/
//location.href = 'index.html#start';
var pages = []; //key value array that maps the pages. Ex. 1=>page2.html, 2=>page3.html
var current = 0; //the index of the starting page. 0 for index.html in this case
var loaded = []; //key value array to prevent loading a page more than once
//get all the pages link inside the #pages div and fill an array
$('#pages a').each(function(index) {
pages[index] = $(this).attr('href');
loaded[$(this).attr('href')] = 0; //initialize all the pages to be loaded to 0. It means that they are not yet been loaded.
});
//on scroll gets when bottom of the page is reached and calls the function do load more content
$(window).scroll(function() {
//Not always the pos == h statement is verified, expecially on mobile devices, that's why a 300px of margin are assumed.
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 300) {
console.log("bottom of the page reached!");
//in some broswer (es. chrome) if the scroll is fast, the bottom
//reach events fires several times, this may cause the page loaging
//more than once. To prevent such situation every time the bottom is
//reached the number of time is added to that page in suach a way to call
//the loadMoreContent page only when the page value in "loaded" array is
//minor or equal to one
loaded[pages[current + 1]] = loaded[pages[current + 1]] + 1;
if (loaded[pages[current + 1]] <= 1)
loadMoreContent(current + 1);
}
});
//loads the next page and append it to the content with a fadeIn effect.
//Before loading the content it shows and hides the loaden Overlay DIV
function loadMoreContent(position) {
//try to load more content only if the counter is minor than the number of total pages
if (position < pages.length) {
$('#loader').fadeIn('slow', function() {
$.get(pages[position], function(data) {
$('#loader').fadeOut('slow', function() {
$('#scroll-container').append(data).fadeIn(999);
current = position;
});
});
});
}
}
jQuery.extend(jQuery.easing, {
easeInOutExpo: function(e, f, a, h, g) {
if (f === 0) {
return a;
}
if (f === g) {
return a + h;
}
if ((f /= g / 2) < 1) {
return h / 2 * Math.pow(2, 10 * (f - 1)) + a;
}
return h / 2 * (-Math.pow(2, -10 * --f) + 2) + a;
}
});
/*jQuery to collapse the navbar on scroll
$(window).scroll(function() {
if ($(".navbar").offset().top > 50) {
$(".navbar-fixed-top").addClass("top-nav-collapse");
} else {
$(".navbar-fixed-top").removeClass("top-nav-collapse");
}
});
*/
//jQuery for page scrolling feature - requires jQuery Easing plugin
$(document).on('click', '.page-scroll', function(e) {
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 2500, 'easeInOutExpo');
e.preventDefault();
});
}
},1);
};
</script>
I have a web page with a top link at the bottom, and anchor for it at the top of the page. I have the following JavaScript to make an element (#primary_nav) fixed after the page has been scrolled past that element:
window.onscroll = scroll;
var scrollFlag = 0;
function scroll() {
if (window.pageYOffset >= 120 && scrollFlag == 0)
{
document.getElementById('content').style.margin = '35px auto 0 auto';
document.getElementById('primary_nav').style.position = 'fixed';
document.getElementById('primary_nav').style.top = '35px';
document.getElementById('primary_nav').style.width = '100%';
scrollFlag = 1;
}
else if(window.pageYOffset < 120 && scrollFlag == 1)
{
document.getElementById('content').style.margin = '0 auto';
document.getElementById('primary_nav').style.position = 'static';
document.getElementById('primary_nav').style.top = 'auto';
document.getElementById('primary_nav').style.width = '1024px';
scrollFlag = 0;
}
}
If I disable this javascript, the link works fine and sends the user back to the top of the page. The anchor is not inside primary_nav or content.
The HTML elements are declared as follows:
<a name='top'></a>
<a href='#top' id='backtotop' title='{$this->lang->words['go_to_top']}'><img src='{$this->settings['img_url']}/top.png' alt='' /></a>
How can I have both the effect of the javascript (sticky navigation) and working anchor links?
You can also check the live site.
So far I've tried
Moving the top anchor all over <body>
Replacing the "Go to top" button's href with javascript (window.location = '#top' and window.scrollTo(0,0)) with both href and onclick. (Both of these work when put into console on Chrome)
This jsfiddle indicates that it's caused by my script conflicting with something else. The only other script accessing it is:
if($('backtotop')){$('backtotop').observe("click",function(e){Event.stop(e);window.scroll(0,0);});}
I figured out part of your issue.
I noticed I can't type location.hash = 'top' and have it jump to top unless I take it out of #content_jump. I assume this is because #content_jump is hidden.
It seems like there might be an event listener on all links that start with # that's causing the issue. I noticed most anchor links are doing little fancy things.
My own Javascript overwrote a function of the same name in the default scripts, which caused the failure. Renaming my scroll function fixed the issue.
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);
}
};
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>