0

I am trying to create a pinterest like effect, and set the positions of the divs via wedding.reposition(). However, I think the outerHeight() function is not working as it returns 0px. I thought this was due to the image not being loaded yet, but I only call the wedding.reposition() after the relevant div has been loaded and appended into the DOM (append is synchronous?).

Interestingly, if I run the wedding.reposition a few seconds later via a setTimeout function, it works. Just wondering if anyone has a solution for this?

//repositions all the elements on the page
wedding.reposition = function() {
  var $post = $(".post");
    //sets col position classes
    for(var i = 0, len = $post.length; i < len; i++) {
      //starts from base 1 rather than base 0
      var colClass = "col" + (i % 4 + 1);
      $post.eq(i).addClass(colClass);

      //implies it is on the second or greater row
      if(i >= 4) {
        var $col = $("." + colClass);
        //gets row of the element in the current column
        var row = Math.floor(i / 4);
        var $prev = $col.eq(row - 1);  

        //determines the height of the current object
        console.log($prev.outerHeight());
        var currentObjectHeight = $prev.position().top + $prev.outerHeight() + 15;
        $col.eq(row).css("top", currentObjectHeight);
      }
    };
};



//PostsView corresponds to the overall view holding individual PostView 
wedding.views.PostsView = Backbone.View.extend({
  el: "#column-container",

  initialize: function(){
    _.bindAll(this);
    this.collection.on("reset", this.render);

    this.collection.fetch();
  },

  render: function(){

    this.collection.each(function(model) {
      this.initializePostView(model);
    }, this);
    wedding.reposition();

  },

  initializePostView: function(model) {
    var html = new wedding.views.PostView({model: model});
    this.$el.append(html.render().el);

  }

});


wedding.views.PostView = Backbone.View.extend({

  className: "post",
  template: "#post-template",

  initialize: function(options) {
    _.bindAll(this);
    this.template = _.template($(this.template).html());
  },

  render: function() {
    this.preload();
    return this;
  },

  preload: function() {
    var image = new Image(); 
    var that = this;
    image.src = this.model.get("src");

    image.onload = function() {
      var html = that.template( {model: that.model.toJSON() });
      that.$el.append(html);
    };
  }
});
Dan Tang
  • 1,273
  • 2
  • 20
  • 35

1 Answers1

0

While you may be appending to the DOM, it doesn't mean the image will be downloaded.

Use the load event for the image, or a plugin such as waitForImages.

alex
  • 479,566
  • 201
  • 878
  • 984
  • I can't seem to get the load function to work. For instance '$("img").load(function(){ console.log("test") });' does not run? – Dan Tang Dec 19 '12 at 05:18
  • @DanTang Need to more context to understand why. – alex Dec 19 '12 at 05:26
  • Hi Alex, this is what I'm running -> im trying to call the reposition function after all the images have been loaded, but it does not seem to work `$(document).ready(function() { //fetches data from server, initializes views wedding.start(); $("img").load(function(){ console.log("test") wedding.reposition(); }); });` – Dan Tang Dec 19 '12 at 05:55
  • @DanTang The `load` event needs to be registered before the images begin to load themselves. – alex Dec 19 '12 at 06:06
  • sorry for asking a stupid question, but how should I do that? I tried declaring the load function first then calling wedding.start() and it won't work too? – Dan Tang Dec 19 '12 at 06:50