【问题标题】:requireJS with JQuery, Masonry, & ImagesLoaded: Object [object Object] has no method 'imagesLoaded'带有 JQuery、Masonry 和 ImagesLoaded 的 requireJS:Object [object Object] 没有方法“imagesLoaded”
【发布时间】:2013-08-18 03:41:29
【问题描述】:

RequireJS 新手在这里。尝试转换一些 JQuery 代码,我以旧方式工作正常,可以使用 RequireJS。

我的页面页眉通过脚本标签加载三个 JS 文件——require.js 本身、我的 require.cfg.js 和具有站点特定功能的 boot/main.js。

相关 require.cfg.js 摘录:

,paths: {
    'boot': 'src/boot'
    ,'jquery': 'lib/jquery.min'
    ,'jquery.masonry': 'lib/plugins/masonry.pkgd.min'
    ,'jquery.imagesloaded': 'lib/plugins/imagesloaded.pkgd.min'
}

,shim: {
    'jquery': {
        exports: 'jQuery'
    }
    ,'jquery.masonry': ['jquery']
    ,'jquery.imagesloaded': ['jquery']
}

boot/main.js:

require([
'jquery',
'jquery.masonry',
'jquery.imagesloaded',
], function($) {

    // 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',});
        });

});

});

我可以确认浏览器正在找到并加载所有这些 JS 文件。我确认如果我这样做:

require([
'jquery',
'jquery.masonry',
'jquery.imagesloaded',
], function($, Masonry, ImagesLoad) {

Masonry 和 ImagesLoaded 变量设置正确......但我不想在没有 jQuery 的情况下继续

但是当我尝试在 JQuery 容器对象上调用 .imagesLoaded() 和 .masonry() 时,我得到:

Uncaught TypeError: Object [object Object] has no method 'imagesLoaded'

如果我注释掉 imagesLoaded 行,我会得到:

Uncaught TypeError: Object [object Object] has no method 'masonry'

不确定我在这里做错了什么......?从我在其他 StackOverflow 问题中读到的内容来看,代码对我来说看起来是正确的......?

谢谢!

更新:

如果我像这样以非 JQuery 方式使用此代码,它可以工作:

        var container = document.querySelector('#container');
        imagesLoaded(container, function() {
            var msnry = new Masonry( container, {
                itemSelector: '.item',
            });
        });

【问题讨论】:

  • 你有这个运行的任何测试位置吗?
  • 嗯,在本地。 :-) 我会把一些东西放在一起......
  • 请参阅reliqry.com/test。我试图去掉所有无关的东西......可能我在这样做时引入了一些其他错误......谢谢你看!
  • 您找到解决方案了吗?遇到同样的问题!
  • 唉,不。我最终重写了代码以使用非 JQuery 方式工作。我会更新我的问题以显示我做了什么。

标签: jquery requirejs jquery-masonry


【解决方案1】:

也尝试为 shim 中的每个插件定义导出...

, 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'
    }
}

【讨论】:

  • 有趣的想法......不幸的是,它给我带来了同样的错误。 (我不得不对你的代码进行一些修改......原来,部分原始问题是我没有正确版本的 masonry & imagesLoaded for requireJS。所以在路径中我现在有'masonry':' bower_components/masonry' 和 'imagesloaded': 'bower_components/imagesloaded',所以我将您的导出更改为 'masonry' 和 'imagesLoaded'。你觉得对吗?)
  • exports 属性是模块公开供其他代码使用的对象。一个很好的例子是导出 '_' 的下划线 js 库。我已经编辑了我的答案以使用您的新路径变量。如果您可以为它创建一个 jsFiddle,可能最容易调试?
【解决方案2】:

试试这个:

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',});
        });

});

});

【讨论】:

  • 谢谢你的想法——我也试过了。如果您查看我的原始问题中的第三个灰色框,我确实尝试过。 Masonry 和 ImagesLoaded 似乎设置正确,但除非我重写原始代码以使用非 JQuery 样式,否则我无法使用它们做任何事情......
【解决方案3】:

好的,我想我有你的问题(和我的问题!)的答案。

如果您要安装托管在 github 上的版本,您可能安装的是“vanilla”版本,而不是 jquery 插件。例如,如果您通过 bower 安装,这就是您将要做的事情,这就是我正在做的事情。

这是我在 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$.masonryjquery.masonry 都指向同一个源(在两个不同的位置),它不是 jquery 插件,它只是砌体的“香草”版本。

相反,只需从 here 下载并解压缩文件 jquery.masonry.js,但它位于您的资产路径中,并为其添加一个依赖于 jquery 的 shim。

完成所有这些之后,它应该可以工作。当然,由于它不是通过 bower 安装的,因此您无法像使用其他 bower 包一样管理依赖项。老实说,我不明白发生了什么,但它看起来像是包维护者方面的问题。

希望对您有所帮助。

更新:虽然上述方法有效,但请注意,从 meta.metafizzy.co 下载的版本相当旧,并且依赖于过时的 jquery 版本。我想我只是打算用香草版本,插件似乎没有维护。

【讨论】:

    【解决方案4】:

    尝试使用 jquery-bridget:https://github.com/desandro/jquery-bridget 将砌体转换为 jquery 插件。我创建了一个由 requirejs 加载的新 js 文件,以确保在应用程序开始运行之前对其进行转换:

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

    然后在我的requirejs文件中

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

    这适用于我的应用程序,它使用 angular 和 angular-masonry(带砖石),因此您可能需要进行一些不同的配置,但希望能给您一些想法。

    【讨论】:

    • 这个技巧很有帮助!让它工作。但是,我必须进行一项修改并添加到 masonry-config.js:Bridget('imagesLoaded', imagesLoaded);
    【解决方案5】:

    在我们的特定案例中,我们在主模板中包含并配置了 RequireJS,但希望在一个特定页面上包含 Masonry/ImagesLoaded。

    我们将代码保存在模板中:

    <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>
    

    然后我们在使用 Masonry 的页面上添加了一个 JavaScript 文件,该文件触发了 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'
                    });
                });
            });
        }
    );
    

    我确信这可以进一步优化,但它解决了错误并且不需要包含任何新包。

    【讨论】:

      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多