简体   繁体   English

Javascript小部件:检查jQuery和jQuery UI的可用性

[英]Javascript widget : Check availability of jQuery and jQuery UI

I need to develop a Javascript Widget (almost finished), and by integrating it into the first site I found a few issues. 我需要开发一个Javascript Widget(几乎完成),并将其集成到第一个站点中,我发现了一些问题。 My Widget needs to load a few libraries (jquery, jquery ui, mustache, ...); 我的Widget需要加载一些库(jquery,jquery ui,mustache等); it is performed by injecting new script tags into the site with this function: 通过使用以下功能将新的脚本标签注入网站来执行此操作:

loadFile: function (filename, filetype) {
    if (filetype == "js") { //if filename is a external JavaScript file
        var fileref = document.createElement('script')
        fileref.setAttribute("type", "text/javascript")
        fileref.setAttribute("src", filename)
    } else if (filetype == "css") { //if filename is an external CSS file
        var fileref = document.createElement("link")
        fileref.setAttribute("rel", "stylesheet")
        fileref.setAttribute("type", "text/css")
        fileref.setAttribute("href", filename)
    }
    if (typeof fileref != "undefined")
        document.getElementsByTagName("head")[0].appendChild(fileref)
}

Is this good practice? 这是好习惯吗? The problem now comes from the fact that the hosting page of the widget might already have jquery and jquery-ui loaded. 现在,问题出在小部件的托管页面可能已经加载了jquery和jquery-ui。 What can I do about it without having to change my code to much? 我无需更改太多代码就可以做什么? I already found this page which describes a solution for jquery. 我已经找到了描述jquery解决方案的页面 But what about jQuery-ui? 但是jQuery-ui呢? I currently have the problem, that my datepickers do not work, as the site already contains datepickers and jquery-ui. 我目前有一个问题,我的日期选择器不起作用,因为该站点已经包含日期选择器和jquery-ui。 Can I change my widget so that my loaded javascript files do not interfear with the including site? 我可以更改我的窗口小部件,以使加载的javascript文件不会与包含站点发生冲突吗? And also make it possible to have two instances of the widget on the same site? 而且还可以在同一站点上拥有窗口小部件的两个实例吗? For the css stuff I already have a solution by creating a diff with a specific Id around the widget content and use that Id in all Css selectors. 对于CSS东西,我已经有了一个解决方案,方法是在小部件内容周围创建一个带有特定ID的diff,并在所有CSS选择器中使用该ID。

So my main concern is about loading my libraries, having them all available in the right version. 因此,我主要关心的是加载我的库,并在正确的版本中提供它们。 My widget should not have any impact on the hosting site and vice versa. 我的窗口小部件对托管站点没有任何影响,反之亦然。 I might include jquery, but the site might use the $ for anything else. 我可能包括jquery,但该网站可能会将$用作其他任何内容。

I already thought about using Basket Js to perform the javascript loading, but this does not solve the injection issue. 我已经考虑过使用Basket Js执行javascript加载,但这不能解决注入问题。

Is there a nice way to include all my libraries into my widget.js without loading external resources? 有没有一种很好的方法可以将我的所有库都包含到我的widget.js中,而无需加载外部资源? So that i can use § for my internal jquery? 这样我就可以对内部jquery使用§了? This must be a general solution working with all types of JS libraries. 这必须是适用于所有类型JS库的通用解决方案。

I also found this but it only works with jQuery and not other libraries. 我也发现了这一点,但它仅适用于jQuery,不适用于其他库。

Any best practices for such a solution? 这种解决方案有最佳实践吗?

Best practice: keep the widget simple. 最佳实践:使小部件保持简单。

Instead of including autoloading functionality, simply specify the requirements and allow the implementing clients to include the correct dependencies: 无需包括自动加载功能,只需指定要求并允许实现的客户端包括正确的依赖项即可:

This widget requires:

+ jQuery 1.9+
+ jQuery UI 1.10.4+

By performing a check for jQuery when your widget is run, you can fail fast and report back to the developer implementing the widget that a dependency is messing: 通过在运行小部件时对jQuery进行检查,您可以快速失败并向实施该小部件的开发人员报告依赖项正在混乱:

if (!window.jQuery) {
    throw new Error('The widget requires jQuery, please check http://widget/docs');
}

Convenience packages 便利套餐

Build tools such as Grunt can be used to to automatically put together "convenience" bundles that include the other libraries. 诸如Grunt之类的构建工具可用于自动组合包含其他库的“便利”包。 I would provide this as an alternative, as clients may wish to avoid this pattern. 我将提供这种方法作为替代方案,因为客户可能希望避免这种模式。 Browsers can used cached copies of popular libraries, even across sites, if the client uses a CDN. 如果客户端使用CDN,则浏览器甚至可以跨站点使用流行库的缓存副本。 For example jQuery has a jQuery CDN . 例如jQuery有一个jQuery CDN

Closures for aliasing 别名的封闭

A closure can be used to keep the widgets variables out of the global namespace, it can also be used to alias jQuery to $ even though $ may mean something entirely different to the rest of the page: 闭包可用于将小部件变量保留在全局名称空间之外,它也可用于将jQuery别名为$,即使$可能与页面的其余部分完全不同:

(function ($) {

    // Widget

}) (window.jQuery)

RequireJS 需求JS

RequireJS can help by organising page dependencies: RequireJS可以通过组织页面依赖项来提供帮助:

define(['jquery-ui'], function($) {

    // Widget

});

This will mean that the implementing clients will need to use RequireJS , one alternative is to provide this as another alternative and have it built from the main source. 这意味着实施客户将需要使用RequireJS ,一种替代方法是将其作为另一种替代方法,并从主要来源进行构建。 With larger projects, using RequireJS to keep components small and separate is a really useful pattern, if you went down this route it is possible to build a RequireJS package into a package that can be used without the client having to include RequireJS by including the Almond shim . 对于较大的项目,使用RequireJS将组件保持较小和分离是一个非常有用的模式,如果沿这条路线走,可以将RequireJS包构建为可以使用的包,而无需客户端通过包含Almond来包含RequireJS。

Bower 凉亭

Bower can also be used to register your widget and specify your dependencies so that implementing clients can grab your widget and all the dependencies they need by running a simple install command: Bower还可以用于注册您的窗口小部件并指定您的依赖关系,以便实施客户端可以通过运行简单的install命令来获取您的窗口小部件及其所需的所有依赖关系:

bower install my-widget

Conclusion 结论

Even by just implementing the top two suggestions it will make your widget lightweight and easy to work with. 即使仅实现前两个建议,它也将使您的小部件轻巧且易于使用。 Say a developer just adds the widget to the page, they will hit an error telling them that there are missing dependencies and to consult the documentation where they can find out exactly what they need to get it working. 假设开发人员只是将小部件添加到页面,他们将遇到一个错误,告诉他们缺少依赖项,并查阅文档,他们可以确切地找到使它起作用所需的内容。

Version compatibility is a problem and there is no simple outright fix as far as I am aware, the latter two tools can really help to minimise the problem. 据我所知,版本兼容性是一个问题,没有简单的直接解决方案,后两种工具确实可以最大程度地减少问题。 Example, say you have two widgets that require fundamentally different and incompatible versions of a library, have no knowledge of each other, by design. 例如,假设您有两个小部件,它们需要一个根本不同且不兼容的库版本,并且彼此之间完全不了解。 Simply the host page has to do a lot to get both widgets working together, or one widget has to be upgraded to use the latest version of the library. 只是宿主页面要做很多工作才能使两个小部件一起工作,或者必须升级一个小部件以使用该库的最新版本。

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

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