8

我的应用程序的 JavaScript/jQuery 包含在一个外部scripts.js文件中。它通常看起来像这样:

$('document').on('ready', function() {
    giraffe();
    elephant();
    zebra();
});

function giraffe() {
    // code
}

function elephant() {
    // code
}

function zebra() {
    // code
}

giraffe()仅用于可用视图/animal/giraffe
elephant()仅用于可用视图/animal/elephant
zebra()仅用于可用视图/animal/zebra,

但是所有 3 都应该在可用的视图上运行/animal/all。这是一个基本示例,但这就是将它们全部放在一个.js文件中的原因,除了将 HTTP 请求保持在最低限度之外。

我的问题是,这会影响 JavaScript 渲染吗?即使giraffe()没有在 上使用(没有要处理的元素)/animal/zebra,它仍然被调用。如果 js/jQuery 无事可做,它会忽略该函数吗?我确信整个脚本都已阅读,这可能需要时间。那么,处理这个问题的最佳方法是什么?

一种解决方案

为了避免冲突,我在 js 文件的顶部创建了条件,只运行活动页面需要的功能:

$('document').on('ready', function() {
    var body = $('body');

    if( body.hasClass('giraffe') ) {
        giraffe();
    }

    if( body.hasClass('elephant') ) {
        elephant();
    }

    if( body.hasClass('zebra') ) {
        zebra();
    }
});

这比我想要的要冗长一些,但它成功地保持了这些功能的模块化/无冲突。我欢迎对此解决方案进行改进。

4

3 回答 3

3

只运行您需要的代码肯定会更好。这并不难;唯一的次要复杂性是处理您的/animals/all案件。如果您想将所有代码保存在一个文件中,您可以这样做:

var animals = {
    giraffe: function() {
        console.log( "I'm a giraffe" );
    },
    elephant: function() {
        console.log( "I'm an elephant" );
    },
    zebra: function() {
        console.log( "I'm a zebra" );
    }
};

$(function() {
    var animal = location.pathname.split('/').pop();
    if( animal == 'all' ) {
        for( var animal in animals ) {
            animals[animal]();
        }
    }
    else if( animal in animals ) {
        animals[animal]();
    }
    else {
        console.log( "I'm a mystery animal" );
    }
});

实际上,您可以通过在 Stack Overflow 上访问这样的 URL 来测试此代码,然后将该代码粘贴到 JavaScript 控制台中:

https://stackoverflow.com/animal/giraffe
https://stackoverflow.com/animal/elephant
https://stackoverflow.com/animal/zebra
https://stackoverflow.com/animal/ocelot
https://stackoverflow。 com/动物/所有

更新:好的,所以你在评论中解释说实际情况有点复杂。我将把这段代码留在这里,以防它对任何人都有用,但对于你的情况,你可能更接近你已经拥有的代码所需要的东西。

WRT 的问题是,当您在与它无关的页面上时,您的动物功能会做什么,当然这取决于它的编码方式。它可能什么都不做,或者它可能有错误,对吧?

由于我们正在讨论 jQuery 代码,因此这里有几个示例。假设您有代码通过 ID 查找元素,然后假设该元素存在:

var zebraElement = $('#zebra')[0];
console.log( zebraElement.value );

#zebra元素存在的页面上,此代码将记录其value属性。(我假设它是一个具有值的元素,例如输入元素。)

但如果#zebrais 不存在,则zebraElementis undefined,并且尝试访问它的操作value将失败并进入调试器。

OTOH,如果你这样编码:

var $zebra = $('#zebra');
console.log( $zebra.val() );

#zebra如果丢失它不会失败,它会成功打印undefined而不会导致错误。

同样,如果您有使用 的代码$().each(),它通常会在缺少元素时运行而不会失败,因为它根本不会执行回调函数:

$('.animal').each( function( i, e ) {
    console.log( $(e).val() );
});

如果没有带有 的元素class="animal"console.log()则将永远无法到达调用。所以没有错误,它什么也没做。

根据您正在做的事情,这可能是一种仅触发您需要的行为的完全合理的方法——只需确保您的代码完全不做任何事情来处理丢失的 DOM 元素。

还请务必阅读尼克的答案以获得更多见解。

还有一个更新......在评论中你提到在body元素上键入类名。一个很好的方法是类似于上面的代码示例。您不需要每个动物的条件,只需要一个循环和一个条件:

var animals = {
    giraffe: function() {
        console.log( "I'm a giraffe" );
    },
    elephant: function() {
        console.log( "I'm an elephant" );
    },
    zebra: function() {
        console.log( "I'm a zebra" );
    }
};

$(function() {
    var $body = $('body');
    for( var animal in animals ) {
        if( $body.hasClass(animal) ) {
            animals[animal]();
        }
    }
});

因此,例如,如果您拥有<body class="giraffe zebra">它,它将调用animals.giraffe()andanimals.zebra()函数。

于 2013-06-11T10:34:28.737 回答
2

这里实际上有两个问题,一个是是否加载所有功能,另一个是是否全部运行。Michael Geary在其他答案中很好地解决了是否全部运行它们(以及一些仅运行所需功能的解决方案)的问题。

那么,您应该全部加载它们吗?您需要权衡下载更大文件所需的时间,而不是发出额外的 http 请求。只有三个“组”功能在 3 个页面之间共享(一个页面使用所有这些功能),当您希望用户定期更改页面时,我会使用一个文件。

一旦你的项目变得非常大,你会想要使用requirejs之类的东西来管理你的脚本并异步加载它们。异步加载您的 js 脚本将提高页面的速度(以及页面的感知速度),如果出现问题(尤其是第三方托管的脚本),您的页面将无法获得帮助。您当然可以在没有库的情况下执行此操作:

使用 HTML5:

<script async src="http://google.com/script.js"></script>

用纯 JS 异步加载有一百万种方法,一种方法:

<script>
  var resource = document.createElement('script'); 
  resource.src = "//google.com/script.js";
  var script = document.getElementsByTagName('script')[0];
  script.parentNode.insertBefore(resource, script);
</script>
于 2013-06-11T10:25:58.283 回答
0

Javascript 将忽略任何未被“调用”的函数。IE。如果您不在 /elephant 或 /all 页面以外的任何页面上调用大象(),那么它将永远不会被使用,也不会给您任何错误。

但是,您可能希望不在页面上显示功能,因为它没有用于更快的页面加载。考虑为某些页面分离 JS 文件,或者通过从后端服务器(例如 PHP)加载某些 JS 脚本来确定需要哪些功能。

于 2013-06-11T10:13:42.003 回答