移动设备中忽略条件依赖关系

时间:2015-02-26 16:41:10

标签: javascript ios mobile requirejs

在构建网站的过程中,我们遇到了VideoJS和Angular之间的冲突,因此当VideoJS库存在时,Angular模块将无法在iOS7中加载。这是一个边缘案例的地狱,页面内容很多比外围视频更重要,所以我们选择为我们的移动用户nix VideoJS并使用图像后备。

现在,请考虑一下requirejs模块的相关代码摘录:

log("checkpoint 1");

var videojs, $ = require('jquery');

if($(".home").length && $(window).outerWidth() > 768){
    log("checkpoint 2a");
    videojs = require('videojs');
    log("checkpoint 2b");

    // video init code here
}

log("checkpoint 3");

在任何移动设备中,日志都会返回:

> checkpoint 1
> checkpoint 3

表示循环未在移动设备中穿透,如预期的那样。然而,与此相反,videojs库仍然被加载 - 这有条件地包括它的整个目的。

我们已经确认这是videojs库被包含的唯一位置,因为当videojs = require('videojs');被注释掉时问题消失 - 库没有出现在资源列表中,并且页面呈现正常。

我们只是设置条件依赖性很差吗?还有另一种方法可以执行此操作,还是我们坚持已知的需求限制?

2 个答案:

答案 0 :(得分:0)

videojs = require('videojs')

我打赌这是源代码(非编译文件)中的一行,然后您可以使用browserify进行编译(或者在发布应用程序之前使用类似的东西)。

问题是,当然,您编译的文件总是需要videojs(除非该行被注释掉),因为您的条件基于仅在运行时可用的决定因素,而不是编译时。

所以,回答你的问题:

  

我们只是设置条件依赖性很差吗?

可能有很多方法可以做到这一点,但我想到的一个方法是将videojs库作为单独的资产提供。您使用(ugh)用户代理解析来确定设备是否正在运行iOS7,如下所示(PHP示例):

<?php if(!is_ios7()) { //pseudo code - UA parsing in here. ?>
 <script src="/path/to/videojs"></script>
<?php } ?>

然后在您的主js文件中,您可以检测videojs全局变量是否存在,然后在需要时使用它。

答案 1 :(得分:-1)

用于生产和测试ENV和移动/桌面使用可以使用此加载器:(来自此git hub项目https://github.com/BoilerplateMVC/Marionette-Require-Boilerplate/blob/master/public/index.html

    // Mobile/Desktop Detection script
            (function(ua, w, d, undefined) {
                // App Environment
                // ---------------
                //  Tip: Set to true to turn on "production" mode
                var production = true,
                        filesToLoad,
                //BoilerplateMVC Helper Methods
                        boilerplateMVC = {
                            loadCSS: function(url, callback) {
                                var link = d.createElement("link");
                                link.type = "text/css";
                                link.rel = "stylesheet";
                                link.href = url;
                                d.getElementsByTagName("head")[0].appendChild(link);
                                if(callback) {
                                    callback();
                                }
                            },
                            loadJS: function(file, callback) {
                                var script = d.createElement("script");
                                script.type = "text/javascript";
                                if (script.readyState) {  // IE
                                    script.onreadystatechange = function() {
                                        if (script.readyState == "loaded"
 || script.readyState == "complete") {
                                            script.onreadystatechange = null;
                                            callback();
                                        }
                                    };
                                } else {  // Other Browsers
                                    script.onload = function() {
                                        callback();
                                    };
                                }
                                if(((typeof file).toLowerCase()) === "object"
 && file["data-main"] !== undefined) {
                                    script.setAttribute("data-main", 
file["data-main"]);
                                    script.async = true;
                                    script.src = file.src;
                                } else {
                                    script.src = file;
                                }
                                d.getElementsByTagName("head")[0].appendChild(script);
                            },
                            loadFiles: function(production, obj, callback) {
                                var self = this;
                                if(production) {
                                    // Loads the production CSS file(s)
                                    self.loadCSS(obj["prod-css"], function() {
                                        // If there are production JavaScript files to load
                                        if(obj["prod-js"]) {
                                            // Loads the correct initialization file (which includes Almond.js)
                                            self.loadJS(obj["prod-js"], callback);
                                        }
                                    });
                                } else {
                                    // Loads the development CSS file(s)
                                    self.loadCSS(obj["dev-css"], function() {
                                        // If there are development Javascript files to load
                                        if(obj["dev-js"]) {
                                            // Loads Require.js and tells Require.js to find the correct intialization file
                                            self.loadJS(obj["dev-js"], callback);
                                        }
                                    });
                                }
                            }
                        };
                // Mobile/Tablet Logic
                if((/iPhone|iPod|iPad|Android|BlackBerry|Opera Mini|IEMobile/).test(ua)) {
                    // Mobile/Tablet CSS and JavaScript files to load
                    filesToLoad = {
                        // CSS file that is loaded when in development mode
                        "dev-css": "css/mobile.css",
                        // CSS file that is loaded when in production mode
                        "prod-css": "css/mobile.min.css",
                        // Require.js configuration file that is loaded when in development mode
                        "dev-js": { "data-main": "js/app/config/config.js", "src": "js/libs/require.js" },
                        // JavaScript initialization file that is also loaded when in development mode
                        "dev-init": "js/app/init/MobileInit.js",
                        // JavaScript file that is loaded when in production mode
                        "prod-init": "js/app/init/MobileInit.min.js",
                        "prod-js": { "data-main": "js/app/config/config.js", "src": "js/libs/require.js" }
                    };
                }
                // Desktop Logic
                else {
                    // Desktop CSS and JavaScript files to load
                    filesToLoad = {
                        // CSS file that is loaded when in development mode
                        "dev-css": "css/desktop.css",
                        // CSS file that is loaded when in production mode
                        "prod-css": "css/desktop.min.css",
                        // Require.js configuration file that is also loaded when in development mode
                        "dev-js": { "data-main": "js/app/config/config.js", "src": "js/libs/require.js" },
                        // JavaScript initialization file that is loaded when in development mode
                        "dev-init": "js/app/init/DesktopInit.js",
                        // JavaScript file that is loaded when in production mode
                        "prod-init": "js/app/init/DesktopInit.min.js",
                        "prod-js": { "data-main": "js/app/config/config.js", "src": "js/libs/require.js" }
                    };
                }
                boilerplateMVC.loadFiles(production, filesToLoad, function() {
                    if(!production && window.require) {
                        require([filesToLoad["dev-init"]]);
                    } else if ( production ) {
                        require([filesToLoad["prod-init"]])
                    }
                });
            })(navigator.userAgent || navigator.vendor || window.opera, window, document);

以及该项目中的其他逻辑:

    var App = new Backbone.Marionette.Application();

    function isMobile() {
        var userAgent = navigator.userAgent || navigator.vendor || window.opera;
        return ((/iPhone|iPod|iPad|Android|BlackBerry|Opera Mini|IEMobile/).test(userAgent));
    }

    App.mobile = isMobile();


require(["App", "jquery", "routers/AppRouter", "controllers/MobileController", "backbone", "marionette", "jquerymobile", "backbone.validateAll"],
    function (App, $, AppRouter, AppController) {
        // Prevents all anchor click handling
        $.mobile.linkBindingEnabled = false;
        // Disabling this will prevent jQuery Mobile from handling hash changes
        $.mobile.hashListeningEnabled = false;

        App.appRouter = new AppRouter({
            controller:new AppController()
        });

        App.start();
    });
相关问题