Adding onload to body

I’m currently trying to develop a plugin that will embed a Google Earth Tour into a WP post / page via a shortcode.

The issue I am running into is that for the tour to load, I have to add an onload="init()" into the <body> tag.

Read More

I can modify a specific template file, but since this is for release, I need to add it dynamically via a hook. Any ideas?

Related posts

Leave a Reply

5 comments

  1. And here’s a jQuery solution (as Mike suggested in his first comment).

    function add_my_scripts() {
        wp_enqueue_script( 'jquery' );
        wp_enqueue_script( 'my_init_script', SCRIPTSRC, 'jquery', '1.0' );
    }
    add_action( 'init', 'add_my_scripts' );
    

    Then add a script to your plug-in that does this:

    jQuery.noConflict();
    
    jQuery(document).ready(function($) {
        init();
    });
    

    This will start jQuery in no conflict mode (if it isn’t already) and add a call to the init() method when the document is ready. It’s a safer method to use than body onready() because the onready() function can only call one thing … so no one else can hook anything to that or add custom script. It’s better to make your plug-in as unobtrusive as possible so other plug-ins don’t interfere or vice-versa.

  2. Here’s an approach. You would add the the add_action() call inside your hook, I believe. The JavaScript I include presumes that the init function has already been defined. If it has not, then this will fail, but including the script seems like a problem you’ve already solved if I’m understanding you right. Note that you don’t necessarily need to add it to wp_foot, you could just as easily add it to wp_head:

    <?php
    
    function mypluginprefix_onload_init() { ?>
    <script language="text/javascript">
    // check for the standards-compliant way to add onload events
    if ( typeof(window.addEventListener) !== 'undefined' )
        window.addEventListener( "load", init, false );
    // or the older msie nonstandard way
    else if ( typeof(window.attachEvent) !== 'undefined' ) {
        window.attachEvent( "onload", init );
    }
    </script>
    <?php }
    
    // this goes in your hook
    add_action('wp_foot', 'mypluginprefix_onload_event');
    ?>
    
  3. Ignoring the potential to do this with jQuery one thing you could do is hook the template_include filter and use ob_start() with a callback. Your callback can then do a string search on '<body' and replace it with '<body onload="init()"' like the following code does. You should be able to drop it directly in your plugin, just be sure to change the names to follow your plugin’s own naming convention:

    <?php
    add_filter('template_include','start_buffer_capture',1);
    function start_buffer_capture($template) {
      ob_start('end_buffer_capture');  // Start Page Buffer
      return $template;
    }
    function end_buffer_capture($buffer) {
      return str_replace('<body','<body onload="init()"',$buffer);
    }
    

    Note that I would not assume the above code to be fully robust yet if I were you. I doubt it will handle all edge cases since I just threw it together to answer your question but minimally it shows you how to accomplish the normal case, and then with some use-case testing I’m sure you” get it to handle all the important edge cases (like what if '<BODY' is uppercase, etc?)

  4. Here’s some JavaScript to dynamically add a callback to the page load, with or without jQuery:

    function add_onload() {
        ?>
        <script type="text/javascript">
        my_onload_callback = function() { alert('Hello!'); }; // test function
    
        if( typeof jQuery == "function" ) { 
            jQuery(my_onload_callback); // document.ready
        } else {
            document.getElementsByTagName('body')[0].onload = my_onload_callback; // body.onload
        }
        </script>
        <?php
    }
    add_action( 'wp_footer', 'add_onload' );
    

    In your case you would just replace the my_onload_callbacks with your init method.

  5. Did some more digging and found a ‘better’ way to get it working (Google makes it hard to get their damn Earth Tours embedded, and their gadget doesn’t work).

    I ended up making a plugin that uses a combination of a shortcode and a custom field.