简体   繁体   English

从另一个.js文件调用一个.js文件中的函数时的命名空间问题

[英]Namespace issue when calling function in one .js file from another .js file

In an attempt to make a swipe-able slideshow for many images, I am attempting to stitch together two plugins, Swipe.js and lazyloader.js . 为了尝试为许多图像制作可滑动的幻灯片,我试图将两个插件Swipe.jslazyloader.js拼接在一起。 I want to have the slideshow timer event from the Swipe plugin call the update function inside of Lazyloader. 我想让Swipe插件中的幻灯片定时器事件调用Lazyloader中的更新功能。 From researching, it seems my problem appears to be one of namespace ; 从研究来看,似乎我的问题似乎是命名空间之一 ; that is, Swipe doesn't know about the stuff inside Lazyloader, and therefore cannot call the function. 也就是说,Swipe不知道Lazyloader里面的东西,因此无法调用该函数。

  1. Given the following code, am I understanding my problem correctly? 鉴于以下代码,我是否正确理解了我的问题?
  2. If so, how can I get Swipe to access Lazyloader's functions? 如果是这样,我如何才能获得Swipe访问Lazyloader的功能?

Thank you. 谢谢。

FOLLOW UP: After Q&A with Cheeso, I see now that I was asking the wrong question in regard to what I ultimately needed to happen. 关注:在与Cheeso进行问答后,我现在看到我在提出最终需要发生的问题时提出了错误的问题。 I add this comment to avoid having any future readers getting confused because of my bad question. 我添加这个评论,以避免因为我的不好问题而让任何未来的读者感到困惑。 This is not about namespace or even about accessing a private function, which shouldn't be done . 这不是关于命名空间甚至是关于访问私有函数的问题, 不应该这样做 This thread is utimately about how inadvisable it may be to try and frankenstein libraries together if you don't really know what you're doing. 如果你真的不知道自己在做什么,这个帖子非常关注如何尝试将frankenstein图书馆放在一起是多么不可取。 ; ; ) END FOLLOW UP )结束后跟随

The callback in swipe.js: swipe.js中的回调:

this.callback = this.options.callback || function() {

the script called inside the html: 在html中调用的脚本:

<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/jquery.lazyload.js" type="text/javascript"></script>
<script src='js/swipe.js' type="text/javascript"></script>

<script type="text/javascript">$(document).ready(function() {


    function myAlert(){
        //call a function from inside jquery.lazyload.js
        alertMe();
    }

    //instantiate a swipe object and pass in a bunch of 
    //options, especially "callback" which fires on every slide change
    window.mySwipe = new Swipe(document.getElementById('slider1'), {
        startSlide: 0,
        speed: 1000,
        auto: 5000,
        callback: function(){
            myAlert();
        }
    });
    // run lazyload on every VISIBLE image with the class "lazy" on load, and on every click
    $("img.lazy").lazyload({event: "click", effect : "fadeIn", threshold: 0,});
    }); 
</script>

jquery.lazyloader.js: jquery.lazyloader.js:

 //outside of the container below, I can be called by myAlert()
 function alertMe() {
        alert("it worked!");
    }


(function($, window) {

    $window = $(window);

    $.fn.lazyload = function(options) {

    ///
    ///Here be a bunch of lazyloader stuff
    ///

    //I work when above, but once I am inside this container, I cannot be called by myAlert(), 
    //and I will error as 'not a valid function'
    function alertMe() {
        alert("it worked! Even inside of this container! ");
    }


})(jQuery, window);

Could be as simple as this: to set the callback option on the Swipe instance to point to a function that does LazyLoader things. 可以这么简单:在Swipe实例上设置callback选项以指向执行LazyLoader事务的函数。 This is just a guess, because I don't know swipe, but I looked at the code dump and saw that callback function; 这只是一个猜测,因为我不知道刷卡,但我查看了代码转储并看到了回调函数; it appears to be the key point of extension for Swipe. 它似乎是Swipe扩展的关键点。

If I'm correct, then it's not a namespace issue at all. 如果我是正确的,那么它根本不是命名空间问题。 It's just what you said - knitting together disparate libraries or modules . 这正是你所说的 - 将不同的库或模块编织在一起 Typically a js module will have an extension point or two that allows this. 通常,js模块将具有一个或两个允许此扩展点的扩展点。 I'm guessing Swipe's extension point is that callback. 我猜Swipe的扩展点就是回调。

Maybe something like this: 也许是这样的:

function myFn() {
  // do whatever lazyload thing you want to do, here. 
}

$(document).ready(function() { 
    var slider1 = new Swipe(document.getElementById('slider1'),
                            {startSlide: 0,
                             speed: 1000,
                             auto: 10000,
                             callback:myFn}); 
    $("img.lazy").lazyload({event: "click"}); 
}); 

You may have to refactor to make either slider1 or some other variables global, so they are accessible outside of the doc.ready function. 您可能必须重构以使slider1或其他变量成为全局变量,因此可以在doc.ready函数之外访问它们。

FOLLOWUP 跟进

You have this: 你有这个:

<script type="text/javascript">
    $(document).ready(function() {   
        function myAlert(){   
            //call a function from inside jquery.lazyload.js   
            alertMe();   
        }   

        //instantiate a swipe object and pass in a bunch of    
        //options, especially "callback" which fires on every slide change   
        window.mySwipe = new Swipe(document.getElementById('slider1'), {   
            startSlide: 0,   
            speed: 1000,   
            auto: 5000,   
            callback: function(){   
                myAlert();   
            }   
        });   
        $("img.lazy").lazyload({event: "click", effect : "fadeIn", threshold: 0,});   
    });    
</script>   

There are several problems with that code. 该代码存在一些问题。 It should be closer to this: 它应该更接近这个:

<script type="text/javascript">
    function myThing(){   
        // ** Do something useful here. This may involve calling
        // ** other functions.  Those functions need not be defined
        // ** within jquery.lazyload.js.
    }   

    $(document).ready(function() {   
        //instantiate a swipe object and pass in a bunch of    
        //options, especially "callback" which fires on every slide change.

        // ** There is no need, as far as I can tell, to assign the
        // ** output to a global variable. (window.mySwipe).  In fact, given
        // ** the code you have, there is no need to retain the output at all. 
        new Swipe(document.getElementById('slider1'), {   
            startSlide: 0,   
            speed: 1000,   
            auto: 5000,   
            // ** Just use the function name. You don't need to define
            // ** a new anonymous function to wrap around it. 
            callback: myThing
        });   
        $("img.lazy").lazyload({event: "click", effect : "fadeIn", threshold: 0,});   
    });    
</script>   

MORE 更多

I suppose that what you want is to lazily load the "next few" images so that they are available as the user swipes through a list. 我想你想要的是懒洋洋地加载“下几张”图像,以便当用户在列表中滑动时它们可用。 From what I read (briefly), you need to call lazyload() only once, for all images on the page. 根据我的内容(简要地说),您需要为页面上的所有图像调用lazyload()一次。 If your images are inside a "container", then specify the container option on lazyload. 如果您的图像位于“容器”内,则在lazyload上指定container选项。 (See http://www.appelsiini.net/projects/lazyload ) The plugin then monitors the viewport for that container and loads images as necessary. (参见http://www.appelsiini.net/projects/lazyload )然后,插件监视该容器的视口并根据需要加载图像。 There is no need to call "lazyload" again, no need for a callback. 无需再次调用“lazyload”,无需回调。

If this is not working, then Swipe and jquery.lazyload.js may not be usable together, because of assumptions made in lazyload. 如果这不起作用,则Swipe和jquery.lazyload.js可能无法一起使用,因为在lazyload中进行了假设。 In that case, you can still get lazy-loading, but you need to do it yourself. 在这种情况下,您仍然可以进行延迟加载,但您需要自己完成。

To do that, eliminate lazyload.js completely . 为此,请完全消除lazyload.js Then, in the Swipe callback, do what you would like lazyload to have done: set the src attribute on the "next" image. 然后,在Swipe回调中,执行您希望lazyload完成的操作:在“下一个”图像上设置src属性。 Setting the attribute will cause the webpage to load the image. 设置该属性将导致网页加载图像。 To get lazy loading, in the original state the src attributes on all images must be blank, or set to some fixed image URL, before the swiping begins. 要获得延迟加载,在原始状态下,所有图像上的src属性必须为空,或者在滑动开始之前设置为某个固定图像URL。 Now, you may ask: in the callback how will you know which image to load? 现在,您可能会问:在回调中,您如何知道要加载哪个图像? And which URL to set into the src attribute? 以及要设置为src属性的URL? That is up for you to determine. 这取决于你确定。 I presume there is some way to get the appropriate information from Swipe in that callback. 我认为有一些方法可以从该回调中的Swipe中获取适当的信息。

If you don't understand this, then you need some instruction or some further reading to establish the basic understanding of how browsers handle images. 如果您不理解这一点,那么您需要一些指导或进一步阅读以建立对浏览器如何处理图像的基本理解。 From my reading, you do not need Swipe to call lazyload's update() . 从我的阅读中,你不需要Swipe来调用lazyload的update()

Some general suggestions: 一些一般性建议:

  • for any module, you should not try to call functions defined internal to that module. 对于任何模块,您不应该尝试调用该模块内部定义的函数。 They are internal for a reason. 它们是内部的原因。

  • for any module, you should not modify its source code unless you are very certain you know what you are doing. 对于任何模块,除非您非常确定自己知道自己在做什么,否则不应修改其源代码。 If you are poking around and trying things, put the code in your own module. 如果您正在四处寻找并尝试一些事情,请将代码放在您自己的模块中。 Your own javascript code belongs in the web page, or in a separate module referenced by the webpage. 您自己的javascript代码属于网页,或者属于网页引用的单独模块。

  • you should probably not be defining functions within $(document).ready() unless you have a good reason. 你可能不应该在$(document).ready()定义函数,除非你有充分的理由。

  • read the documentation. 阅读文档。 I had never heard of Swipe or lazyload before today. 在今天之前我从未听说过Swipe或lazyload。 The suggestions I made here about them - specifically, regarding the callback on Swipe, and the container option on lazyload - came from me reading the doc for how to use them. 我在这里提出的关于它们的建议 - 特别是关于Swipe上的回调和lazyload上的容器选项 - 来自我阅读文档以了解如何使用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM