手机版

基于RequireJS和JQuery的模块化编程——常见问题综合分析

时间:2021-11-04 来源:互联网 编辑:宝哥软件园 浏览:

随着js的代码逻辑越来越重,一个js文件可能有几千行,不利于开发和维护。最近,非常符合逻辑的js被拆分成模块。在关于使用requirejs还是seajs的争论中,还是偏向于requirejs。毕竟公文更专业。

但是,即使有完整的官方文档,仍然存在很多问题,比如jquery-ui的使用。

以下是我遇到的问题和解决方法的分步说明。

对AMD和CMD的理解。

AMD(异步模块定义)是requirejs的典型,而CMD(通用模块定义)是淘宝seajs的典型。

它们的相似之处在于它们都异步加载js。但不同的是,require.js会在加载后立即执行;Seajs直到主函数需要执行时才执行。

如果使用seajs,初始加载和执行效率会更高,但是js在使用过程中可能会被拿走执行,所以可能会卡住,影响用户体验(既然我也没试过,请不要见怪)。Requirejs是在开始时执行所有加载的js。此时,如果您的模块中有一些执行方法,它们可能不会按照您想要的顺序执行。

所以,如果你习惯异步编程,想要一个完美的文档,建议使用requirejs;如果您想对执行顺序有特殊的要求并促进开发,您也可以使用seajs。

如何解决requirejs中的循环依赖问题?

如果你定义的某个A模块使用B模块,B模块使用A模块,就会抛出循环依赖的异常。

例如,我在这里写了一个循环依赖的例子。

主页:

!键入html head/head dyscript data-main=' test . js ' src=' http : lib/require . js '/script/body/html main方法:

require js . config({ BaseURl : })。/'});requirejs(['js/a'],函数(a){ console . log(' in test ');a . testfromb();});在a.js模块中,atest()方法提供了调用b的方法,testfromb()方法调用b。

define(function(require){ var b=require(' js/b ');console . log(' in a ');返回{ atest : function(){ console . log(' test in a ');},test from b : function(){ console . log(' a '中的testfrombb . btest();} }});在模块b中,调用a的方法。

define(function(require){ var a=require(' js/a ');console . log(' in b ');返回{ btest : function(){ console . log(' b中的测试');a . atest();} }});这相当于A调用B的方法,但是B的方法依赖于A的方法,造成循环依赖。浏览器会提示一个错误:

未捕获的错误:尚未为上下文:加载模块名称“js/a”

根据官方文件,这种设计问题应该尽量避免。无法避免怎么办?您可以按如下方式修改b模块:

define(function(require){//var a=require(' js/a ');console . log(' in b ');返回{ btest : function(){ console . log(' b中的测试');需要(' js/a ')。atest();} }});在这种情况下,只有在执行atest()方法后,才会加载a模块。这时很明显A模块已经加载完毕。您可以看到输出信息:

在ba.js:3中在atest.js:6中在testa.js:9中在testfromb中在ab.js:6中在ba.js:6中在测试a

同样,修改可能也不容易。此时,模块加载的顺序从B开始.

循环依赖的源代码,请参考云盘。

如何在requirejs中使用jquery?

如果很容易使用jquery,只需在main.js中添加相应的依赖关系即可:

require js . config({ BaseURl : })。/',path : { ' jquery ' : ' lib/jquery ' } });requirejs(['jquery'],function ($){ $('#test ')。html(' test ');});如何在requirejs中使用jquery插件对于jquery插件,常见的是传入一个jquery对象,并在这个jquery对象的基础上添加相应的插件方法。首先,我们需要添加jquery插件的依赖性。这里,我们以两个插件为例:——jquery-ui和jquery-datatablerequires . config({ baseurl 3360 })。/',path : { ' jquery ' 3360 ' lib/jquery ',' jquery-ui':'lib/jquery-ui ',' jquery-dataTables ' : ' lib/jquery . dataTables ' },shim : { ' jquery-ui ' :[' jquery '],' jquery-dataTables ' :[' jquery ']});requirejs(['jquery ',' jquery-ui ',' jquery-dataTables'],函数($){ 0.});因为所有jquery插件都需要依赖jquery,所以可以在shim中指定依赖关系。除了上面的用法外,还可以使用commonJS样式的调用:define(function(require){ var $=require(' jquery ');需要(' jquery-ui ');需要(' jquery-DataTables ');//以下都是测试。您可以忽略var _test=$('#test ')。_ test . selectmenu({ width : 180,change : function(event,ui){ console . log(' change ');} });返回{ test : function(){//test jquery-ui _ test . append($(' option test 1/option test 1/option '));_test.selectmenu(“刷新”);//test jquery-datatables var _ table=$(“table”);_ table . DataTable();} }});但是,执行上述代码将报告一个异常:

未捕获类型错误: _table.dataTable不是函数

这是因为dataTables不是一个require-style模块,所以如果以这种方式直接引入,它将不会执行其内部匿名函数。您可以修改它的匿名函数并传入$对象。在最后一行:

*/return $ . fn . DataTable;//}));就是这样}($);//这里增加了这个匿名函数,传入了$ object。}(窗口、文档));这也是网上搜索的方法,但原则是经验不足。

示例代码可以参考云盘。因为引入的资源不完整,会报错,可以直接忽略。因为UI插件可以执行,说明已经成功了。

requirejs中使用jquery-ui的问题。

由于requirejs将在加载js文件后立即执行,如果jquery ui插件需要刷新DOM页面,可能会导致页面的事件无效。

例如,在您的模块被加载之后,一个click事件被绑定到页面的一个元素$(“# test”)。但是,如果使用UI插件,插件会重新呈现DOM元素,测试对应的点击事件将无效。

解决方法:

将事件绑定推迟到DOM元素呈现后,再手动触发绑定;您也可以使用事件捕获来代替DOM元素的事件绑定(太麻烦了.不推荐)。

例如,在DOM重构的JS模块中,在用于呈现的代码下:

要求(' xxx ')。init events();常见场景:

例如,我在页面中使用jquery-steps作为UI插件,它将重新呈现页面。这导致我在开始时绑定的事件失效.只有当这个js重构页面的时候,我才能重新绑定。

以上基于RequireJS和JQuery对模块化编程——常见问题的综合分析,是边肖分享的全部内容,希望能给大家一个参考和支持。

版权声明:基于RequireJS和JQuery的模块化编程——常见问题综合分析是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。