Search code examples
javascriptmustachejquery-masonry

Conflict between masonryjs and mustachejs


I have a syntax error somewhere in my javascript that seems to be slipping by. I can either access the content through a file into a mustache template, or I can hard code the items (images and audio) and have the items smoothly fill up the page with masonryjs. But when I try to add both, either or both will not work. Here is my CodePen

What I expect to happen is to have my page generated from the document feeding my mustache template. But it should stack smoothly like sites like Pinterest where the images tile neatly since I used masonryjs.

Here is the code that works with Masonry

HTML

<div id="content" class="container clearfix">

  <div class="item">
    <img src="http://assets.wtfisthat.info/img/1.JPG" alt="" />
    <audio controls>
      <source src="http://assets.wtfisthat.info/audio/1.wav">
    </audio>
  </div>

  <div class="item">
    <img src="http://assets.wtfisthat.info/img/2.JPG" alt="" />
    <audio controls>
      <source src="http://assets.wtfisthat.info/audio/2.wav">
    </audio>
  </div>

  <div class="item">
    <img src="http://assets.wtfisthat.info/img/3.JPG" alt="" />
    <audio controls>
      <source src="http://assets.wtfisthat.info/audio/3.wav">
    </audio>
  </div>

  <div class="item">
    <img src="http://assets.wtfisthat.info/img/4.JPG" alt="" />
    <audio controls>
      <source src="http://assets.wtfisthat.info/audio/4.wav">
    </audio>
  </div>
<!-- The rest of the items handcoded -->
</div> <!--/ #container -->

JS

$(document).ready(function() {

  // Initialize Masonry
  $('#content').masonry({
    columnWidth: 320,
    itemSelector: '.item',
    isFitWidth: true,
    isAnimated: !Modernizr.csstransitions
  }).imagesLoaded(function() {
      $(this).masonry('reload');
    });

});

But When I add mustache so that it is not hand coded, then it fails. I tried doing this

HTML

<div id="content" class="container clearfix">
  <div id="image-list"></div>


  <script id="imgtpl" type="text/template">
    {{#images}}
      <div class="item">
        <img src="http://assets.wtfisthat.info/img/{{img}}" alt="{{alt}}">
        <audio controls>
          <source src="http://assets.wtfisthat.info/audio/{{id}}.wav">
        </audio>
      </div>
    {{/images}}
  </script>
</div> <!--/ #container -->

JS

// Streams in the data from the JSON file
$(function() {
  $.getJSON('https://s3-us-west-2.amazonaws.com/s.cdpn.io/101702/img.js',   function(data) {
    var template = $('#imgtpl').html();
    var html = Mustache.to_html(template, data);
    $('#image-list').html(html);
  });
});

$(document).ready(function() {

  // Initialize Masonry
  $('#content').masonry({
    columnWidth: 320,
    itemSelector: '.item',
    isFitWidth: true,
    isAnimated: !Modernizr.csstransitions
  }).imagesLoaded(function() {
    $(this).masonry('reload');
  });

});

Solution

  • solved here: http://codepen.io/anon/pen/MwJXpW

    I've changed your code so that the new elements are appended to the existing ones, instead of pushing them inside their own div.

    Then, you should use masonry('appended', $elements) once the elements are added, as explained in this page: adding items.

    Here is the modified script:

    $.getJSON('https://s3-us-west-2.amazonaws.com/s.cdpn.io/101702/img.js', function(data) {
        var template = $('#imgtpl').html();
        var html = Mustache.to_html(template, data);
        var $html = $(html)
        $('#content').append($html).masonry( 'appended', $html); 
      });