Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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">
<a href="http://twitter.com/share" class="twitter-share-button" data-url="" data-count="vertical" data-via="#">Tweet</a><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>
like image 315
markratledge Avatar asked Mar 05 '13 03:03

markratledge


2 Answers

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 */

});
like image 66
Olly Hodgson Avatar answered Sep 21 '22 15:09

Olly Hodgson


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.

like image 41
FibreFoX Avatar answered Sep 19 '22 15:09

FibreFoX