2

I'm using the wookmark jquery plugin, it works fine with every browsers except safari both on pc and mac, the images seems to be overlapped each other. How can I fix it?

thanks in advance Alex

here there's the code of the plugin:

$.fn.wookmark = function(options) {

  if(!this.wookmarkOptions) {
    this.wookmarkOptions = $.extend( {
        container: $('body'),
        offset: 2,
        autoResize: false,
        itemWidth: $(this[0]).outerWidth(),
        resizeDelay: 50
      }, options);
  } else if(options) {
    this.wookmarkOptions = $.extend(this.wookmarkOptions, options);
  }

  // Layout variables.
  if(!this.wookmarkColumns) {
    this.wookmarkColumns = null;
    this.wookmarkContainerWidth = null;
  }

  // Main layout function.
  this.wookmarkLayout = function() {
    // Calculate basic layout parameters.
    var columnWidth = this.wookmarkOptions.itemWidth + this.wookmarkOptions.offset;
    var containerWidth = this.wookmarkOptions.container.width();
    var columns = Math.floor((containerWidth+this.wookmarkOptions.offset)/columnWidth);
    var offset = Math.round((containerWidth - (columns*columnWidth-this.wookmarkOptions.offset))/2);

    // If container and column count hasn't changed, we can only update the columns.
    var bottom = 0;
    if(this.wookmarkColumns != null && this.wookmarkColumns.length == columns) {
      bottom = this.wookmarkLayoutColumns(columnWidth, offset);
    } else {
      bottom = this.wookmarkLayoutFull(columnWidth, columns, offset);
    }

    // Set container height to height of the grid.
    this.wookmarkOptions.container.css('height', bottom+'px');
  };

  /**
   * Perform a full layout update.
   */
  this.wookmarkLayoutFull = function(columnWidth, columns, offset) {
    // Prepare Array to store height of columns.
    var heights = [];
    while(heights.length < columns) {
      heights.push(0);
    }

    // Store column data.
    this.wookmarkColumns = [];
    while(this.wookmarkColumns.length < columns) {
      this.wookmarkColumns.push([]);
    }

    // Loop over items.
    var item, top, left, i=0, k=0, length=this.length, shortest=null, shortestIndex=null, bottom = 0;
    for(; i<length; i++ ) {
      item = $(this[i]);

      // Find the shortest column.
      shortest = null;
      shortestIndex = 0;
      for(k=0; k<columns; k++) {
        if(shortest == null || heights[k] < shortest) {
          shortest = heights[k];
          shortestIndex = k;
        }
      }

      // Postion the item.
      item.css({
        position: 'absolute',
        top: shortest+'px',
        left: (shortestIndex*columnWidth + offset)+'px'
      });

      // Update column height.
      heights[shortestIndex] = shortest + item.outerHeight() + this.wookmarkOptions.offset;
      bottom = Math.max(bottom, heights[shortestIndex]);

      this.wookmarkColumns[shortestIndex].push(item);
    }

    return bottom;
  };

  /**
   * This layout function only updates the vertical position of the 
   * existing column assignments.
   */
  this.wookmarkLayoutColumns = function(columnWidth, offset) {
    var heights = [];
    while(heights.length < this.wookmarkColumns.length) {
      heights.push(0);
    }

    var i=0, length = this.wookmarkColumns.length, column;
    var k=0, kLength, item;
    var bottom = 0;
    for(; i<length; i++) {
      column = this.wookmarkColumns[i];
      kLength = column.length;
      for(k=0; k<kLength; k++) {
        item = column[k];
        item.css({
          left: (i*columnWidth + offset)+'px',
          top: heights[i]+'px'
        });
        heights[i] += item.outerHeight() + this.wookmarkOptions.offset;

        bottom = Math.max(bottom, heights[i]);
      }
    }

    return bottom;
  };

  // Listen to resize event if requested.
  this.wookmarkResizeTimer = null;
  if(!this.wookmarkResizeMethod) {
    this.wookmarkResizeMethod = null;
  }
  if(this.wookmarkOptions.autoResize) {
    // This timer ensures that layout is not continuously called as window is being dragged.
    this.wookmarkOnResize = function(event) {
      if(this.wookmarkResizeTimer) {
        clearTimeout(this.wookmarkResizeTimer);
      }
      this.wookmarkResizeTimer = setTimeout($.proxy(this.wookmarkLayout, this), this.wookmarkOptions.resizeDelay)
    };

    // Bind event listener.
    if(!this.wookmarkResizeMethod) {
      this.wookmarkResizeMethod = $.proxy(this.wookmarkOnResize, this);
    }
    $(window).resize(this.wookmarkResizeMethod);
  };

  /**
   * Clear event listeners and time outs.
   */
  this.wookmarkClear = function() {
    if(this.wookmarkResizeTimer) {
      clearTimeout(this.wookmarkResizeTimer);
      this.wookmarkResizeTimer = null;
    }
    if(this.wookmarkResizeMethod) {
      $(window).unbind('resize', this.wookmarkResizeMethod);
    }
  };

  // Apply layout
  this.wookmarkLayout();

  // Display items (if hidden).
  this.show();
};
Pradeep
  • 3,258
  • 1
  • 23
  • 36
user2132472
  • 21
  • 1
  • 3

3 Answers3

4

Late to the party here but for future developers having issues, this could help you....

If Images are slow to load it can cause Wookmark to have issues with the sizing of elements. One easy way to solve this is to re-call the handler like byroncorrales has stated above. However doing it this way doesn't make sure that everything has loaded. We want to wait for the DOM to be fully loaded then call the handler for a second time.

So at the end add this simple piece of jQuery.

$(window).load(function() {
    handler.wookmark(options);
});
Jamie Turner
  • 569
  • 1
  • 6
  • 14
3

Try to call handler.wookmark twice

 $(document).ready(function() {
    var options = {
      autoResize: true, // This will auto-update the layout when the browser window is resized.
      container: $('#tiles'), // Optional, used for some extra CSS styling
      offset: 10, // Optional, the distance between grid items
      flexibleWidth: 210 // Optional, the maximum width of a grid item
    };
    var handler = $('#tiles li');
    $('#tiles').imagesLoaded(function() {
      // Prepare layout options.
      // Get a reference to your grid items.
      // Call the layout function.
      handler.wookmark(options);
    });
    handler.wookmark(options);
});
byroncorrales
  • 745
  • 6
  • 12
  • 1
    Note: The `imagesLoaded` method is a [plugin](http://desandro.github.io/imagesloaded/), not a part jQuery itself. – Tim Jun 17 '15 at 17:22
0

or make another refresh even later - only this way it worked for me (I am loading images and videos)

$(window).load(function() {
  setTimeout(function() {
    handler.wookmark(options);
  }, 500);
});
Picard
  • 3,745
  • 3
  • 41
  • 50