This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation

jQuery plugins that create complex display elements often take information from the visibility or dimensions of their containing DOM element. A consequence is that if they are first rendered inside a DOM element that is hidden they get the wrong information and have glitches in their display.

The following solution is one that addon developers can use to unilaterally improve the rendering of a problematic jQuery plugin. It doesn't require modifications inside a jQuery plugin. It doesn't require cooperating code from elsewhere in Concrete5 or other add-ons to trigger rendering events.

$(document).ready(function(){
  var t;
  var startWhenVisible = function (){
    if ($('#id').is(':visible')){
      window.clearInterval(t);
      $('#id').jQueryPluginStart({optionnames:'optionvalues'});
      return true;
    } 
    return false;
  };
  if (!startWhenVisible()){
    t = window.setInterval(function(){startWhenVisible();},100);      
  }
});

In this example, .jQueryPluginStart({optionnames:'optionvalues'}) is the method that starts the jQuery plugin.

If the containing DOM is visible ('#id'), it is run straight away. There is no appreciable overhead or change to the way the plugin works.

If not, a polling event is started to run every 100ms (a reasonable value that many users won't even notice), and the jQuery plugin started when its container becomes visible. An important part to never forget is to clear the timer when the plugin is started window.clearInterval(t).

If you are not using jQuery, this pure JavaScript version is slightly modified from code contributed by Ollie from Formigo and is used in the Formigo Directions block.

window.onload = function() {
  var t;
  var elem;
  var startWhenVisible = function (){
    elem = document.getElementById('id');
    if (elem.offsetWidth > 0 || elem.offsetHeight > 0){
      window.clearInterval(t);
      startWhatever(parameters);
      return true;
    } 
    return false;
  };   
  if (!startWhenVisible()){
    t = window.setInterval(function(){startWhenVisible();},100);      
  }
}

For a more sophisticated solution that can be applied to any existing block with no coding, have a look at Blocks by AJAX.

The standard maps block has the above code implemented in concrete5.6.1. The pull request is on GitHub (now closed)

Read more How-tos by JohntheFish

Loading Conversation