requireJS with JQuery, Masonry, & ImagesLoaded: Object [object Object] has no method 'imagesLoaded'

前端 未结 5 2210
春和景丽
春和景丽 2021-02-09 16:19

RequireJS newbie here. Trying to convert some JQuery code I had working fine in the old way to work w/ RequireJS.

Header of my page loads three JS files via script tags

相关标签:
5条回答
  • 2021-02-09 16:48

    Try this instead:

    require([
    'jquery',
    'jquery.masonry',
    'jquery.imagesloaded',
    ], function($, Masonry, ImagesLoad) {
    
        // The following code worked just fine when I included it in the header of the page as-is
    $(function() {
    
        var $container = $('#container');
        // This doesn't work
        $container.imagesLoaded(function() {
                        // Neither does this
                $('#container').masonry({itemSelector : '.item',});
            });
    
    });
    
    });
    
    0 讨论(0)
  • 2021-02-09 16:50

    Ok, I think I have the answer to your problem (and mine!).

    If you're installing the versions hosted on github, you're probably installing the "vanilla" version, not the jquery plugin. That's what you'll be doing if you install via bower, for example, which is what I was doing.

    Here's what I found with a search on bower:

    % bower search masonry
    # jquery-masonry git://github.com/desandro/masonry
    # masonry git://github.com/desandro/masonry.git
    # $.masonry git://github.com/tysoncadenhead/masonry
    # angular-masonry git://github.com/passy/angular-masonry.git
    # jquery.masonry git://github.com/tysoncadenhead/masonry.git
    

    AFAICT, jquery-masonry, $.masonry and jquery.masonry are all pointing to the same source (in two different locations), and it's not the jquery plugin it's just the "vanilla" version of masonry.

    Instead, just download from here and extract the file jquery.masonry.js, but it in your assets path, and add a shim for it with a dependency on jquery.

    After you do all that, it should work. Of course since it's not installed through bower, you can't manage dependencies as you would with other bower packages. I honestly don't understand what's going on but it looks like a problem on the package-maintainer's side.

    Hope that helps.

    UPDATE: Although the above works, note that the version downloaded from meta.metafizzy.co is quite old and depends on an outdated version of jquery. I think I'm just going to go with the vanilla version, it seems that the plugin is not being maintained.

    0 讨论(0)
  • 2021-02-09 17:07

    Try using jquery-bridget: https://github.com/desandro/jquery-bridget to convert masonry to a jquery plugin. I created a new js file that gets loaded by requirejs to ensure it is converted before the application starts running:

    //masonry-config.js:
    'use strict'
    
    define(['jquery-bridget', 'masonry'], function(Bridget, Masonry){
        Bridget('masonry', Masonry );
    });   
    

    Then in my requirejs file

    //main.js
    require.config({
       paths: {
           'masonry-config': 'masonry-config'
           .....
       },
       shim: {  
           'angular-masonry': ['angular', 'masonry'],
           'angular' : {
             deps: ['imagesloaded', 'masonry-config'],
             exports: 'angular'
           },
           'masonry': ['imagesloaded'],
       } 
    }
    

    This is for my app using angular and angular-masonry (with masonry) so you might need to config a little differently but hopefully that give you some idea.

    0 讨论(0)
  • 2021-02-09 17:12

    Try defining exports for each plugin in the shim too...

    , paths: {
        boot: 'src/boot'
        , jquery: 'bower_components/jquery'
        , masonry: 'bower_components/masonry',
        , imagesloaded: 'bower_components/imagesloaded'
    }
    , shim: {
        jquery: {
            exports: 'jQuery'
        }
        , masonry: {
            deps : ['jquery'],
            exports : 'jQuery.masonry'
        }
        , imagesloaded: {
            deps : ['jquery'],
            exports : 'jQuery.imagesLoaded'
        }
    }
    
    0 讨论(0)
  • 2021-02-09 17:14

    In our particular case we had RequireJS included and configured in our main template, but wanted to include Masonry/ImagesLoaded on one particular page.

    We kept our code in the template:

    <script type="text/javascript" src="/path/to/require.min.js"></script>
    <script type="text/javascript">
        require.config({
            waitSeconds: 0,
            paths: {
                'jquery': "/path/to/jquery.min",
                // ...
            },
            shim: {
                // ...
            }
        });
        require(["jquery", /* ... */], function ($) {
            // ...
        });
    </script>
    

    Then we included a JavaScript file after this, on the page that used Masonry, that triggered Masonry/ImagesLoaded:

    requirejs(['jquery', 'https://unpkg.com/masonry-layout@4.2.2/dist/masonry.pkgd.min.js', 'https://unpkg.com/imagesloaded@4.1.4/imagesloaded.pkgd.min.js'],
        function ($, Masonry, ImagesLoaded) {
            $(document).ready(function () {
                ImagesLoaded('.js-masonry', function () {
                    new Masonry('.js-masonry', {
                        // This was required for us, but from what I can tell shouldn't need to be/may need to be updated per-usage.
                        itemSelector: '.item'
                    });
                });
            });
        }
    );
    

    I'm sure this could be further optimized, but it resolved the errors and didn't require any new packages to be included.

    0 讨论(0)
提交回复
热议问题