<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [toc] seajs.config ============ 用來對 Sea.js 進行配置。 ``` seajs.config({ // 設置路徑,方便跨目錄調用 paths: { 'arale': 'https://a.alipayobjects.com/arale', 'jquery': 'https://a.alipayobjects.com/jquery' }, // 設置別名,方便調用 alias: { 'class': 'arale/class/1.0.0/class', 'jquery': 'jquery/jquery/1.10.1/jquery' } }); ``` 更多配置項請參考: 配置 -- 可以對 Sea.js 進行配置,讓模塊編寫、開發調試更方便。 --- seajs.config `seajs.config(options)` ------------------------------------ 用來進行配置的方法。 ~~~ seajs.config({ // 別名配置 alias: { 'es5-safe': 'gallery/es5-safe/0.9.3/es5-safe', 'json': 'gallery/json/1.0.2/json', 'jquery': 'jquery/jquery/1.10.1/jquery' }, // 路徑配置 paths: { 'gallery': 'https://a.alipayobjects.com/gallery' }, // 變量配置 vars: { 'locale': 'zh-cn' }, // 映射配置 map: [ ['http://example.com/js/app/', 'http://localhost/js/app/'] ], // 預加載項 preload: [ Function.prototype.bind ? '' : 'es5-safe', this.JSON ? '' : 'json' ], // 調試模式 debug: true, // Sea.js 的基礎路徑 base: 'http://example.com/path/to/base/', // 文件編碼 charset: 'utf-8' }); ~~~ 支持以下配置選項: ### alias `Object` 當模塊標識很長時,可以使用 `alias` 來簡化。 ~~~ seajs.config({ alias: { 'jquery': 'jquery/jquery/1.10.1/jquery', 'app/biz': 'http://path/to/app/biz.js', } }); ~~~ ~~~ define(function(require, exports, module) { var $ = require('jquery'); //=> 加載的是 http://path/to/base/jquery/jquery/1.10.1/jquery.js var biz = require('app/biz'); //=> 加載的是 http://path/to/app/biz.js }); ~~~ 使用 `alias`,可以讓文件的真實路徑與調用標識分開,有利于統一維護。 ### paths `Object` 當目錄比較深,或需要跨目錄調用模塊時,可以使用 `paths` 來簡化書寫。 ~~~ seajs.config({ paths: { 'gallery': 'https://a.alipayobjects.com/gallery', 'app': 'path/to/app', } }); ~~~ ~~~ define(function(require, exports, module) { var underscore = require('gallery/underscore'); //=> 加載的是 https://a.alipayobjects.com/gallery/underscore.js var biz = require('app/biz'); //=> 加載的是 path/to/app/biz.js }); ~~~ `paths` 配置可以結合 `alias` 配置一起使用,讓模塊引用非常方便。 ### vars `Object` 有些場景下,模塊路徑在運行時才能確定,這時可以使用 `vars` 變量來配置。 ~~~ seajs.config({ vars: { 'locale': 'zh-cn' } }); ~~~ ~~~ define(function(require, exports, module) { var lang = require('./i18n/{locale}.js'); //=> 加載的是 path/to/i18n/zh-cn.js }); ~~~ `vars` 配置的是模塊標識中的變量值,在模塊標識中用 `{key}` 來表示變量。 ### map `Array` 該配置可對模塊路徑進行映射修改,可用于路徑轉換、在線調試等。 ~~~ seajs.config({ map: [ [ '.js', '-debug.js' ] ] }); ~~~ ~~~ define(function(require, exports, module) { var a = require('./a'); //=> 加載的是 path/to/a-debug.js }); ~~~ ##Sea.js 的調試接口 使用 Sea.js,無論開發時還是上線后,調試都很方便。下面一一闡述。 seajs.cache Object 通過 seajs.cache,可以查閱當前模塊系統中的所有模塊信息。 比如,打開 seajs.org,然后在 WebKit Developer Tools 的 Console 面板中輸入 seajs.cache,可以看到: ~~~ Object > http://seajs.org/docs/assets/main.js: x > https://a.alipayobjects.com/jquery/jquery/1.10.1/jquery.js: x > __proto__: Object ~~~ 這些就是文檔首頁用到的模塊。展開某一項可以看到模塊的具體信息,含義可參考:CMD 模塊定義規范 中的 module 小節。 `seajs.resolve Function` 類似 require.resolve,會利用模塊系統的內部機制對傳入的字符串參數進行路徑解析。 ~~~ seajs.resolve('jquery'); // => http://path/to/jquery.js seajs.resolve('./a', 'http://example.com/to/b.js'); // => http://example.com/to/a.js ~~~ `seajs.resolve`方法不光可以用來調試路徑解析是否正確,還可以用在插件開發環境中。 ###seajs.require Function 全局的 `require` 方法,可用來直接獲取模塊接口,比如 ~~~ seajs.use(['a', 'b'], function() { var a = seajs.require('a') var b = seajs.require('b') // do something... }) ~~~ ###seajs.data Object 通過 seajs.data,可以查看 seajs 所有配置以及一些內部變量的值,可用于插件開發。當加載遇到問題時,也可用于調試。 ### preload `Array` 使用 `preload` 配置項,可以在普通模塊加載前,提前加載并初始化好指定模塊。 ~~~ // 在老瀏覽器中,提前加載好 ES5 和 json 模塊 seajs.config({ preload: [ Function.prototype.bind ? '' : 'es5-safe', this.JSON ? '' : 'json' ] }); ~~~ `preload` 中的空字符串會被忽略掉。 **注意**:`preload` 中的配置,需要等到 `use` 時才加載。比如: ~~~ seajs.config({ preload: 'a' }); // 在加載 b 之前,會確保模塊 a 已經加載并執行好 seajs.use('./b'); ~~~ `preload` 配置不能放在模塊文件里面: ~~~ seajs.config({ preload: 'a' }); define(function(require, exports) { // 此處執行時,不能保證模塊 a 已經加載并執行好 }); ~~~ ### debug `Boolean` 值為 `true` 時,加載器不會刪除動態插入的 script 標簽。插件也可以根據 debug 配置,來決策 log 等信息的輸出。 ### base `String` Sea.js 在解析頂級標識時,會相對 `base` 路徑來解析。詳情請參閱 [模塊標識](https://github.com/seajs/seajs/issues/258) **在 `seajs@2.3.0` 之前,Sea.js 會根據 sea.js 的路徑去猜測 `base` 路徑,一般為路徑上含有 seajs 字符串的上一級路徑。在 `seajs@2.3.0` 后,去掉了這個模糊的猜測。我們推薦始終手動設置一個準確的 `base` 路徑**。 ### charset `String | Function` 獲取模塊文件時,`<script>` 或 `<link>` 標簽的 `charset` 屬性。 默認是 `utf-8` `charset` 還可以是一個函數: ~~~ seajs.config({ charset: function(url) { // xxx 目錄下的文件用 gbk 編碼加載 if (url.indexOf('http://example.com/js/xxx') === 0) { return 'gbk'; } // 其他文件用 utf-8 編碼 return 'utf-8'; } }); ~~~ 提示 -- ### 多次配置自動合并 `seajs.config` 可以多次運行,每次運行時,會對配置項進行合并操作: ~~~ seajs.config({ alias: { 'jquery': 'path/to/jquery.js', 'a': 'path/to/a.js' }, preload: ['seajs-text'] }); seajs.config({ alias: { 'underscore': 'path/to/underscore.js', 'a': 'path/to/biz/a.js' }, preload: ['seajs-combo'] }); ~~~ 上面兩處 `config` 運行的結果是: ~~~ alias = { 'jquery': 'path/to/jquery.js', 'underscore': 'path/to/underscore.js', 'a': 'path/to/biz/a.js' }; preload = ['seajs-text', 'seajs-combo']; ~~~ 即:`config` 會自動合并不存在的項,對存在的項則進行覆蓋。 ### 插件的配置 插件可以給 `Sea.js` 添加配置項,請查看具體插件了解相關配置。 ### 配置文件 配置可以直接寫在 html 頁面上,也可以獨立出來成為一個文件。 ~~~ config.js seajs.config({ ... }); ~~~ 獨立成一個文件時,一般通過 script 標簽在頁面中同步引入。 --- 常用的配置項是 `alias`、`paths`、`base`,其他配置項有需要時,來查查文檔就會用了。 seajs.use ========= 用來在頁面中加載一個或多個模塊。 ~~~ // 加載一個模塊 seajs.use('./a'); // 加載一個模塊,在加載完成時,執行回調 seajs.use('./a', function(a) { a.doSomething(); }); // 加載多個模塊,在加載完成時,執行回調 seajs.use(['./a', './b'], function(a, b) { a.doSomething(); b.doSomething(); }); ~~~ 更多用法請參考: 模塊的加載啟動 ------- Sea.js 是一個模塊加載器,模塊加載器需要實現兩個基本功能: 1. 實現模塊定義規范,這是模塊系統的基礎。 2. 模塊系統的啟動與運行。 ### 模塊定義規范的實現 這就是 `define`,`require`,`exports`,`module` 的實現。具體實現細節,有興趣的可以看 Sea.js 的源碼:[seajs/src](https://github.com/seajs/seajs/tree/master/src)。可以按照 [Gruntfile.js](https://github.com/seajs/seatools/blob/master/Gruntfile.js#L98) 中聲明的合并順序閱讀,核心是 `module.js` 文件。 `define` 等方法的具體使用,請閱讀:[CMD 模塊定義規范](https://github.com/seajs/seajs/issues/242) ### 模塊系統的啟動 有了 `define` 等模塊定義規范的實現,我們可以開發出很多模塊。但光有一堆模塊不管用,我們還得讓它們能跑起來。 首先就是啟動問題。比如在 Node 中,啟動很簡單: ``` $ node main.js ``` 這就是啟動。 再舉一個例子,操作系統的啟動:大家都知道的,按一下開機鍵就好。 在 Sea.js 里,要啟動模塊系統很簡單: ~~~ <script src="path/to/sea.js"></script> <script> seajs.use('./main'); </script> ~~~ seajs.use `Function` -------------------- 用來在頁面中加載模塊。 ### seajs.use `seajs.use(id, callback?)` 通過 `use` 方法,可以在頁面中加載任意模塊: ~~~ // 加載模塊 main,并在加載完成時,執行指定回調 seajs.use('./main', function(main) { main.init(); }); ~~~ `use` 方法還可以一次加載多個模塊: ~~~ // 并發加載模塊 a 和模塊 b,并在都加載完成時,執行指定回調 seajs.use(['./a', './b'], function(a, b) { a.init(); b.init(); }); ~~~ `callback` 參數可選,省略時,表示無需回調。 ### 與 DOM ready 的關系 **注意**:`seajs.use` 與 `DOM ready` 事件沒有任何關系。如果某些操作要確保在 `DOM ready` 后執行,需要使用`jquery` 等類庫來保證,比如: ~~~ seajs.use(['jquery', './main'], function($, main) { $(document).ready(function() { main.init(); }); }); ~~~ sea.js 的引入 ---------- 在調用 `seajs.use` 之前,需要先引入 `sea.js` 文件,推薦直接使用 `script` 標簽同步引入: ``` <script src="path/to/sea.js"></script> ``` 為了滿足某些場景下的性能優化需求,也可以將 `sea.js` 的源碼內嵌: ``` <script> // sea.js 的源碼 </script> ``` 注意:代碼內嵌時,需要通過 `seajs.config` 手動配置 `base` 路徑。 最佳實踐 ---- 1. `seajs.use` 理論上只用于加載啟動,不應該出現在 `define` 中的模塊代碼里。在模塊代碼里需要異步加載其他模塊時,推薦使用 `require.async` 方法。 2. 引入 `sea.js` 時,可以把 `sea.js` 與其他文件打包在一起,可提前合并好,或利用 combo 服務動態合并。無論哪一種方式,為了讓 `sea.js` 內部能快速獲取到自身路徑,推薦手動加上 `id` 屬性: ``` <script src="path/to/sea.js" id="seajsnode"></script> ``` 加上 `seajsnode` 值,可以讓 `sea.js` 直接獲取到自身路徑,而不需要通過其他機制去自動獲取。這對性能和穩定性會有一定提升,推薦默認都加上。 小結 -- `seajs.use` 是模塊加載器必備的一個接口。在 `seajs` 上,還有用于配置的 `config` 方法、方便調試的`cache` 等接口,這些會在接下來的文檔中詳細闡述。 define ====== 用來定義模塊。Sea.js 推崇一個模塊一個文件,遵循統一的寫法: ~~~ define(function(require, exports, module) { // 模塊代碼 }); ~~~ require.async ============= 用來在模塊內部異步加載一個或多個模塊。 ~~~ define(function(require) { // 異步加載一個模塊,在加載完成時,執行回調 require.async('./b', function(b) { b.doSomething(); }); // 異步加載多個模塊,在加載完成時,執行回調 require.async(['./c', './d'], function(c, d) { c.doSomething(); d.doSomething(); }); }); ~~~ exports ======= 用來在模塊內部對外提供接口。 ~~~ define(function(require, exports) { // 對外提供 foo 屬性 exports.foo = 'bar'; // 對外提供 doSomething 方法 exports.doSomething = function() {}; }); ~~~ module.exports ============== 與 `exports` 類似,用來在模塊內部對外提供接口。 ~~~ define(function(require, exports, module) { // 對外提供接口 module.exports = { name: 'a', doSomething: function() {}; }; }); ~~~ CMD 模塊定義規范 ---------- 在 Sea.js 中,所有 JavaScript 模塊都遵循 CMD([Common Module Definition](https://github.com/cmdjs/specification/blob/master/draft/module.md)) 模塊定義規范。該規范明確了模塊的基本書寫格式和基本交互規則。 在 CMD 規范中,一個模塊就是一個文件。代碼的書寫格式如下: ``` define(factory); ``` define `Function` ----------------- `define` 是一個全局函數,用來定義模塊。 ### define `define(factory)` `define` 接受 `factory` 參數,`factory` 可以是一個函數,也可以是一個對象或字符串。 `factory` 為對象、字符串時,表示模塊的接口就是該對象、字符串。比如可以如下定義一個 JSON 數據模塊: ``` define({ "foo": "bar" }); ``` 也可以通過字符串定義模板模塊: ``` define('I am a template. My name is {{name}}.'); ``` `factory` 為函數時,表示是模塊的構造方法。執行該構造方法,可以得到模塊向外提供的接口。`factory` 方法在執行時,默認會傳入三個參數:`require`、`exports` 和 `module`: ~~~ define(function(require, exports, module) { // 模塊代碼 }); ~~~ ### define `define(id?, deps?, factory)` `define` 也可以接受兩個以上參數。字符串 `id` 表示模塊標識,數組 `deps` 是模塊依賴。比如: ~~~ define('hello', ['jquery'], function(require, exports, module) { // 模塊代碼 }); ~~~ `id` 和 `deps` 參數可以省略。省略時,可以通過構建工具自動生成。 **注意**:帶 `id` 和 `deps` 參數的 `define` 用法不屬于 CMD 規范,而屬于 [Modules/Transport](https://github.com/cmdjs/specification/blob/master/draft/transport.md) 規范。 ### define.cmd `Object` 一個空對象,可用來判定當前頁面是否有 CMD 模塊加載器: ~~~ if (typeof define === "function" && define.cmd) { // 有 Sea.js 等 CMD 模塊加載器存在 } ~~~ require `Function` ------------------ `require` 是 `factory` 函數的第一個參數。 ### require `require(id)` `require` 是一個方法,接受 [模塊標識](https://github.com/seajs/seajs/issues/258) 作為唯一參數,用來獲取其他模塊提供的接口。 ~~~ define(function(require, exports) { // 獲取模塊 a 的接口 var a = require('./a'); // 調用模塊 a 的方法 a.doSomething(); }); ~~~ **注意**:在開發時,`require` 的書寫需要遵循一些 [簡單約定](https://github.com/seajs/seajs/issues/259)。 ### require.async `require.async(id, callback?)` `require.async` 方法用來在模塊內部異步加載模塊,并在加載完成后執行指定回調。`callback` 參數可選。 ~~~ define(function(require, exports, module) { // 異步加載一個模塊,在加載完成時,執行回調 require.async('./b', function(b) { b.doSomething(); }); // 異步加載多個模塊,在加載完成時,執行回調 require.async(['./c', './d'], function(c, d) { c.doSomething(); d.doSomething(); }); }); ~~~ **注意**:`require` 是同步往下執行,`require.async` 則是異步回調執行。`require.async` 一般用來加載可延遲異步加載的模塊。 ### require.resolve `require.resolve(id)` 使用模塊系統內部的路徑解析機制來解析并返回模塊路徑。該函數不會加載模塊,只返回解析后的絕對路徑。 ~~~ define(function(require, exports) { console.log(require.resolve('./b')); // ==> http://example.com/path/to/b.js }); ~~~ 這可以用來獲取模塊路徑,一般用在插件環境或需動態拼接模塊路徑的場景下。 exports `Object` ---------------- `exports` 是一個對象,用來向外提供模塊接口。 ~~~ define(function(require, exports) { // 對外提供 foo 屬性 exports.foo = 'bar'; // 對外提供 doSomething 方法 exports.doSomething = function() {}; }); ~~~ 除了給 `exports` 對象增加成員,還可以使用 `return` 直接向外提供接口。 ~~~ define(function(require) { // 通過 return 直接提供接口 return { foo: 'bar', doSomething: function() {} }; }); ~~~ 如果 `return` 語句是模塊中的唯一代碼,還可簡化為: ~~~ define({ foo: 'bar', doSomething: function() {} }); ~~~ 上面這種格式特別適合定義 JSONP 模塊。 **特別注意**:下面這種寫法是錯誤的! ~~~ define(function(require, exports) { // 錯誤用法!!! exports = { foo: 'bar', doSomething: function() {} }; }); ~~~ 正確的寫法是用 `return` 或者給 `module.exports` 賦值: ~~~ define(function(require, exports, module) { // 正確寫法 module.exports = { foo: 'bar', doSomething: function() {} }; }); ~~~ **提示**:`exports` 僅僅是 `module.exports` 的一個引用。在 `factory` 內部給 `exports` 重新賦值時,并不會改變 `module.exports` 的值。因此給 `exports` 賦值是無效的,不能用來更改模塊接口。 module `Object` --------------- `module` 是一個對象,上面存儲了與當前模塊相關聯的一些屬性和方法。 ### module.id `String` 模塊的唯一標識。 ~~~ define('id', [], function(require, exports, module) { // 模塊代碼 }); ~~~ 上面代碼中,`define` 的第一個參數就是模塊標識。 ### module.uri `String` 根據模塊系統的路徑解析規則得到的模塊絕對路徑。 ~~~ define(function(require, exports, module) { console.log(module.uri); // ==> http://example.com/path/to/this/file.js }); ~~~ 一般情況下(沒有在 `define` 中手寫 `id` 參數時),`module.id` 的值就是 `module.uri`,兩者完全相同。 ### module.dependencies `Array` `dependencies` 是一個數組,表示當前模塊的依賴。 ### module.exports `Object` 當前模塊對外提供的接口。 傳給 `factory` 構造方法的 `exports` 參數是 `module.exports` 對象的一個引用。只通過 `exports` 參數來提供接口,有時無法滿足開發者的所有需求。 比如當模塊的接口是某個類的實例時,需要通過 `module.exports`來實現: ~~~ define(function(require, exports, module) { // exports 是 module.exports 的一個引用 console.log(module.exports === exports); // true // 重新給 module.exports 賦值 module.exports = new SomeClass(); // exports 不再等于 module.exports console.log(module.exports === exports); // false }); ~~~ **注意**:對 `module.exports` 的賦值需要同步執行,不能放在回調函數里。下面這樣是不行的: ~~~ // x.js define(function(require, exports, module) { // 錯誤用法 setTimeout(function() { module.exports = { a: "hello" }; }, 0); }); ~~~ 在 y.js 里有調用到上面的 x.js: ~~~ // y.js define(function(require, exports, module) { var x = require('./x'); // 無法立刻得到模塊 x 的屬性 a console.log(x.a); // undefined }); ~~~ 小結 -- 這就是 CMD 模塊定義規范的所有內容。經常使用的 API 只有 `define`, `require`, `require.async`, `exports`,`module.exports` 這五個。其他 API 有個印象就好,在需要時再來查文檔,不用刻意去記。 與 RequireJS 的 AMD 規范相比,CMD 規范盡量保持簡單,并與 CommonJS 和 Node.js 的 Modules 規范保持了很大的兼容性。通過 CMD 規范書寫的模塊,可以很容易在 Node.js 中運行,后續會介紹。 `require`, `exports` 和 `module` 三個參數可酌情省略,具體用法如下。 require ======= `require` 用來獲取指定模塊的接口。 ~~~ define(function(require) { // 獲取模塊 a 的接口 var a = require('./a'); // 調用模塊 a 的方法 a.doSomething(); }); ~~~ 注意,`require` 只接受字符串直接量作為參數,詳細約定請閱讀: require 書寫約定 ------------ 使用 Sea.js 書寫模塊代碼時,需要遵循一些簡單規則。 > 只是書寫和調試時的規范!!!構建后的代碼完全不需要遵循下面的約定!!!!!! ### 1. 正確拼寫 模塊 factory 構造方法的第一個參數 **必須** 命名為 `require` 。 ~~~ // 錯誤! define(function(req) { // ... }); // 正確! define(function(require) { // ... }); ~~~ ### 2. 不要修改 不要重命名 `require` 函數,或在任何作用域中給 `require` 重新賦值。 ~~~ // 錯誤 - 重命名 "require"! var req = require, mod = req("./mod"); // 錯誤 - 重定義 "require"! require = function() {}; // 錯誤 - 重定義 "require" 為函數參數! function F(require) {} // 錯誤 - 在內嵌作用域內重定義了 "require"! function F() { var require = function() {}; } ~~~ ### 3. 使用直接量 `require` 的參數值 **必須** 是字符串直接量。 ~~~ // 錯誤! require(myModule); // 錯誤! require("my-" + "module"); // 錯誤! require("MY-MODULE".toLowerCase()); // 正確! require("my-module"); ~~~ 在書寫模塊代碼時,必須遵循這些規則。其實只要把 `require` **看做是語法關鍵字** 就好啦。 關于動態依賴 ------ 有時會希望可以使用 `require` 來進行條件加載: ~~~ if (todayIsWeekend) require("play"); else require("work"); ~~~ 但請牢記,從靜態分析的角度來看,這個模塊同時依賴 play 和 work 兩個模塊,加載器會把這兩個模塊文件都下載下來。 這種情況下,推薦使用 `require.async` 來進行條件加載。 Why? ---- 這些約定初看起來會有些小不爽,其實也的確可以通過每次都編譯的方式來去掉這些限制。但編譯的方式,會給開發調試帶來麻煩,代碼的實現復雜度也會增加。Sea.js 的核心設計原則是保持簡單,遵循 [New Jersey Approach](http://blog.jobbole.com/19062/): > 簡單性:設計必須簡單,這既是對實現的要求,也是對接口的要求。實現的簡單要比接口的簡單更加重要。簡單是設計中需要第一重視的因素。 因為簡單,所以可靠!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看