UNPKG

gs-events

Version:

事件分发器(同步)

488 lines (430 loc) 31.3 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <base data-ice="baseUrl" href="../../"> <title data-ice="title">src/EventDispatcher.js | gs-events</title> <link type="text/css" rel="stylesheet" href="css/style.css"> <link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css"> <script src="script/prettify/prettify.js"></script> <script src="script/manual.js"></script> <meta name="description" content="&#x4E8B;&#x4EF6;&#x5206;&#x53D1;&#x5668;&#xFF08;&#x540C;&#x6B65;&#xFF09;"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="gs-events"><meta property="twitter:description" content="&#x4E8B;&#x4EF6;&#x5206;&#x53D1;&#x5668;&#xFF08;&#x540C;&#x6B65;&#xFF09;"></head> <body class="layout-container" data-ice="rootContainer"> <header> <a href="./">Home</a> <a href="identifiers.html">Reference</a> <a href="source.html">Source</a> <div class="search-box"> <span> <img src="./image/search.png"> <span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span> </span> <ul class="search-result"></ul> </div> <a style="position:relative; top:3px;" href="https://github.com/guless/events"><img width="20px" src="./image/github.png"></a></header> <nav class="navigation" data-ice="nav"><div> <ul> <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/CustomEvent.js~CustomEvent.html">CustomEvent</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/Event.js~Event.html">Event</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/EventDispatcher.js~EventDispatcher.html">EventDispatcher</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/EventListener.js~EventListener.html">EventListener</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/EventListenerOptions.js~EventListenerOptions.html">EventListenerOptions</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/EventPhase.js~EventPhase.html">EventPhase</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-interface">I</span><span data-ice="name"><span><a href="class/src/IEventDispatcher.js~IEventDispatcher.html">IEventDispatcher</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-interface">I</span><span data-ice="name"><span><a href="class/src/IEventListener.js~IEventListener.html">IEventListener</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-interface">I</span><span data-ice="name"><span><a href="class/src/IEventListenerOptions.js~IEventListenerOptions.html">IEventListenerOptions</a></span></span></li> </ul> </div> </nav> <div class="content" data-ice="content"><h1 data-ice="title">src/EventDispatcher.js</h1> <pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// @Copyright ~2018 &#x261C;Samlv9&#x261E; and other contributors /// @MIT-LICENSE | 1.0.0 | https://api.guless.com/ /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// }| /// }| /// }| &#x3000; &#x3078;&#x3000;&#x3000;&#x3000; &#xFF0F;| /// _______ _______ ______ }| /&#x3000;&#x2502;&#x3000;&#x3000; &#xFF0F; &#xFF0F; /// / ___ | |_ __ \ .&apos; ____ &apos;. }| &#x2502;&#x3000;Z &#xFF3F;,&#xFF1C;&#x3000;&#xFF0F;&#x3000;&#x3000; /`&#x30FD; /// | (__ \_| | |__) | | (____) | }| &#x2502;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x30FD;&#x3000;&#x3000; /&#x3000;&#x3000;&#x3009; /// &apos;.___`-. | __ / &apos;_.____. | }| Y&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;`&#x3000; /&#x3000;&#x3000;/ /// |`\____) | _| | \ \_ | \____| | }| &#xFF72;&#x25CF;&#x3000;&#xFF64;&#x3000;&#x25CF;&#x3000;&#x3000;&#x2282;&#x2283;&#x3008;&#x3000;&#x3000;/ /// |_______.&apos; |____| |___| \______,&apos; }| ()&#x3000; v&#x3000;&#x3000;&#x3000;&#x3000;|&#x3000;&#xFF3C;&#x3008; /// |=========================================\| &#x3000;&gt;&#xFF70; &#xFF64;_&#x3000; &#x30A3;&#x3000; &#x2502; &#xFF0F;&#xFF0F; /// |&gt; LESS IS MORE || / &#x3078;&#x3000;&#x3000; /&#x3000;&#xFF89;&#xFF1C;|&#xFF3C;&#xFF3C; /// `=========================================/| &#x30FD;_&#xFF89;&#x3000;&#x3000;(_&#xFF0F;&#x3000; &#x2502;&#xFF0F;&#xFF0F; /// }| 7&#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x3000; |&#xFF0F; /// }| &#xFF1E;&#x2015;r&#xFFE3;&#xFFE3;`&#xFF70;&#x2015;&#xFF3F;` /// }| /// }| /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the &quot;Software&quot;), to deal /// in the Software without restriction, including without limitation the rights /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell /// copies of the Software, and to permit persons to whom the Software is /// furnished to do so, subject to the following conditions: /// /// The above copyright notice and this permission notice shall be included in all /// copies or substantial portions of the Software. /// /// THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /// THE SOFTWARE. import IEventDispatcher from &quot;./IEventDispatcher&quot;; import IEventListener from &quot;./IEventListener&quot;; import IEventListenerOptions from &quot;./IEventListenerOptions&quot;; import Event from &quot;./Event&quot;; import EventPhase from &quot;./EventPhase&quot;; import EventListener from &quot;./EventListener&quot;; /** * &#x5B9A;&#x4E49;&#x6240;&#x6709;&#x5177;&#x5907;&#x4E8B;&#x4EF6;&#x6D3E;&#x53D1;&#x529F;&#x80FD;&#x5BF9;&#x8C61;&#x7684;&#x57FA;&#x7C7B;&#x3002; * @implements {IEventDispatcher} * @since 1.0.0 */ export default class EventDispatcher /*&lt; implements IEventDispatcher &gt;*/ { /** * &#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x6D3E;&#x53D1;&#x5668;&#x3002; * @param {IEventDispatcher} [target=null] - &#x6307;&#x5B9A;&#x6D3E;&#x53D1;&#x5668;&#x7684;&#x4EE3;&#x7406;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x3002; * @since 1.0.0 */ constructor( target = null ) { /** * @type {IEventDispatcher} */ this._targetDispatcher = (target || this); /** * @type { {[type:String|Symbol]:Array&lt;EventListener&gt;} } */ this._listenerRegister = {}; /** * @type { {type:String|Symbol}: Boolean } */ this._listenerLockers = {}; /** &#x4E8B;&#x4EF6;&#x4EE3;&#x7406; */ if ( this !== this._targetDispatcher ) { if ( this._targetDispatcher.hasEventListener || this._targetDispatcher.addEventListener || this._targetDispatcher.removeEventListener || this._targetDispatcher.dispatchEvent ) { throw new TypeError(&quot;&#x65E0;&#x6CD5;&#x4E3A;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x521B;&#x5EFA;&#x4EE3;&#x7406;&#xFF0C;&#x56E0;&#x4E3A;&#x5176;&#x81EA;&#x8EAB;&#x5DF2;&#x7ECF;&#x5B9E;&#x73B0;&#x4E86;&#x4E00;&#x5957;&#x4E8B;&#x4EF6;&#x7CFB;&#x7EDF;&#x3002;&quot;); } this._targetDispatcher.addEventListener = this.addEventListener .bind(this); this._targetDispatcher.removeEventListener = this.removeEventListener .bind(this); this._targetDispatcher.hasEventListener = this.hasEventListener .bind(this); this._targetDispatcher.dispatchEvent = this.dispatchEvent .bind(this); this._targetDispatcher._dispatchToListeners = this._dispatchToListeners.bind(this); } } /** * &#x6CE8;&#x518C;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x4FA6;&#x542C;&#x5668;&#x3002; * * &#x5982;&#x679C;&#x6D4F;&#x89C8;&#x5668;&#x652F;&#x6301; {@link Symbol} &#x7C7B;&#x578B;&#xFF0C;&#x5219;&#x4E8B;&#x4EF6;&#x7C7B;&#x578B;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; {@link Symbol} &#x5BF9;&#x8C61;&#xFF0C;&#x8FD9;&#x6837;&#x53EF;&#x4EE5;&#x9632;&#x6B62; * &#x4F60;&#x7684;&#x4E8B;&#x4EF6;&#x88AB;&#x5176;&#x4ED6;&#x4EBA;&#x610F;&#x5916;&#x7684;&#x79FB;&#x9664;&#x3002; * * &#x4E8B;&#x4EF6;&#x4FA6;&#x542C;&#x5668;&#x53EF;&#x4EE5;&#x6CE8;&#x518C;&#x5230;&#x6D3E;&#x53D1;&#x4E8B;&#x4EF6;&#x7684;&#x4EFB;&#x4F55;&#x4E00;&#x4E2A;&#x9636;&#x6BB5;&#xFF0C;**&#x6355;&#x83B7;&#x9636;&#x6BB5;**&#x548C;**&#x5192;&#x6CE1;&#x9636;&#x6BB5;**&#x7684;&#x4FA6;&#x542C;&#x5668;&#x662F;&#x76F8;&#x4E92;&#x72EC;&#x7ACB;&#x7684;&#x3002; * &#x56E0;&#x6B64;&#x4F7F;&#x7528;&#x4E0D;&#x540C;&#x7684; `useCapture` &#x503C;&#x5C06;&#x6CE8;&#x518C;&#x4E0D;&#x540C;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x3002;&#x540C;&#x6837;&#x79FB;&#x9664;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x4E5F;&#x9700;&#x8981;&#x6307;&#x5B9A;&#x4E0D;&#x540C;&#x7684; `useCapture` &#x503C;&#x3002; * * &#x4E8B;&#x4EF6;&#x5904;&#x7406;&#x51FD;&#x6570;&#x9ED8;&#x8BA4;&#x7684;&#x4F5C;&#x7528;&#x57DF;&#x4E3A;&#x6D3E;&#x53D1;&#x5668;&#xFF08;`EventDispatcher`&#xFF09;&#x5BF9;&#x8C61;&#x6216;&#x8005;&#x5176;&#x4EE3;&#x7406;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; `options.scope` * &#x53EF;&#x4EE5;&#x4E3A;&#x4E8B;&#x4EF6;&#x5904;&#x7406;&#x51FD;&#x6570;&#x6307;&#x5B9A;&#x4F5C;&#x7528;&#x57DF;&#x3002;&#x4F46;&#x662F;&#x5982;&#x679C;&#x6CE8;&#x518C;&#x7684;&#x662F;&#x4E00;&#x4E2A;&#x5B9E;&#x73B0;&#x4E86; {@link IEventListener} &#x63A5;&#x53E3;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x5219;&#x76F4;&#x63A5; * &#x8C03;&#x7528;&#x5176; `handleEvent()` &#x65B9;&#x6CD5;&#x5904;&#x7406;&#x4E8B;&#x4EF6;&#xFF0C;&#x5E76;&#x4E14;&#x4F5C;&#x7528;&#x57DF;&#x59CB;&#x7EC8;&#x6307;&#x5411;&#x8BE5; `IEventListener` &#x5BF9;&#x8C61;&#x3002; * * &#x901A;&#x8FC7;&#x6307;&#x5B9A; `options.once` &#x9009;&#x9879;&#xFF0C;&#x53EF;&#x4EE5;&#x6307;&#x5B9A;&#x4FA6;&#x542C;&#x5668;&#x5728;&#x6267;&#x884C;&#x540E;&#xFF0C;&#x662F;&#x5426;&#x81EA;&#x52A8;&#x4ECE;&#x5217;&#x8868;&#x4E2D;&#x79FB;&#x9664;&#x3002; * * &#x4F18;&#x5148;&#x7EA7;&#x9AD8;&#xFF08;`options.priority`&#xFF09;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x4F1A;&#x5728;&#x6D3E;&#x53D1;&#x4E8B;&#x4EF6;&#x65F6;&#x4F18;&#x5148;&#x8C03;&#x7528;&#x3002;&#x76F8;&#x540C;&#x4F18;&#x5148;&#x7EA7;&#x7684;&#x60C5;&#x51B5;&#x4F1A;&#x6309;&#x7167;&#x6CE8;&#x518C;&#x7684;&#x5148;&#x540E; * &#x987A;&#x5E8F;&#x8C03;&#x7528;&#x4FA6;&#x542C;&#x5668;&#x3002;&#x5206;&#x522B;&#x4F7F;&#x7528;&#x4E0D;&#x540C;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x6CE8;&#x518C;&#x76F8;&#x540C;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x65F6;&#xFF0C;&#x4EE5;&#x6700;&#x540E;&#x4E00;&#x6B21;&#x6CE8;&#x518C;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x4E3A;&#x51C6;&#x3002; * * @param {String|Symbol} type - &#x4E8B;&#x4EF6;&#x7C7B;&#x578B;&#x3002; * @param {Function|IEventListener} handler - &#x6307;&#x5B9A;&#x4E8B;&#x4EF6;&#x5904;&#x7406;&#x51FD;&#x6570;&#x6216;&#x8005;&#x662F;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x4FA6;&#x542C;&#x5668;&#x3002; * @param {Boolean|IEventListenerOptions} [options=false] - &#x6307;&#x5B9A;&#x4FA6;&#x542C;&#x5668;&#x914D;&#x7F6E;&#x9009;&#x9879;&#x3002; * @example * const dispatcher = new EventDispatcher(); * * /// &#x5728;&#x5192;&#x6CE1;&#x9636;&#x6BB5;&#x6CE8;&#x518C;&#x4FA6;&#x542C;&#x5668;&#x3002; * dispatcher.addEventListener(&quot;custom&quot;, ( evt ) =&gt; {}); * dispatcher.addEventListener(&quot;custom&quot;, ( evt ) =&gt; {}, false); * * /// &#x5728;&#x6355;&#x83B7;&#x9636;&#x6BB5;&#x6CE8;&#x518C;&#x4FA6;&#x542C;&#x5668;&#x3002; * dispatcher.addEventListener(&quot;custom&quot;, ( evt ) =&gt; {}, true); * * /// &#x6307;&#x5B9A;&#x4E8B;&#x4EF6;&#x5904;&#x7406;&#x51FD;&#x6570;&#x7684;&#x4F5C;&#x7528;&#x57DF;&#x3002; * const target = {}; * dispatcher.addEventListener(&quot;custom&quot;, ( evt ) =&gt; { * console.log(target === this); // true * }, { &quot;scope&quot;: target }); * * /// &#x6CE8;&#x518C;&#x4E00;&#x6B21;&#x6027;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x3002; * dispatcher.addEventListener(&quot;custom&quot;, ( evt ) =&gt; { * /// &#x8BE5;&#x51FD;&#x6570;&#x6267;&#x884C;&#x540E;&#xFF0C;&#x5C06;&#x81EA;&#x52A8;&#x4ECE;&#x5217;&#x8868;&#x4E2D;&#x79FB;&#x9664;&#x3002; * }, { &quot;once&quot;: true }); * * /// &#x5C3D;&#x7BA1;&#x8BE5;&#x4FA6;&#x542C;&#x5668;&#x540E;&#x6CE8;&#x518C;&#x7684;&#xFF0C;&#x4F46;&#x662F;&#x56E0;&#x4E3A;&#x5177;&#x6709;&#x8F83;&#x9AD8;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#xFF0C;&#x6240;&#x4EE5;&#x4F1A;&#x5148;&#x88AB;&#x8C03;&#x7528;&#x3002; * dispatcher.addEventListener(&quot;custom&quot;, ( evt ) =&gt; { * console.log(1); * }, { &quot;priority&quot;: 1 }); * * /// &#x76F8;&#x540C;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x4F7F;&#x7528;&#x4E0D;&#x7528;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x591A;&#x6B21;&#x6CE8;&#x518C;&#xFF0C;&#x4EE5;&#x6700;&#x540E;&#x4E00;&#x6B21;&#x6CE8;&#x518C;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x4E3A;&#x51C6;&#x3002; * const handler = ( evt ) =&gt; {}; * dispatcher.addEventListener(&quot;custom&quot;, handler, { &quot;priority&quot;: 1 }); * dispatcher.addEventListener(&quot;custom&quot;, handler, { &quot;priority&quot;: 2 }); // &#x53EA;&#x4F1A;&#x6CE8;&#x518C;&#x4E00;&#x4E2A;&#x4F18;&#x5148;&#x7EA7;&#x4E3A; 2 &#x7684;&#x4FA6;&#x542C;&#x5668;&#x3002; * @see {@link IEventListenerOptions} * @since 1.0.0 */ addEventListener( type, handler, options = false ) { if ( !handler ) { throw new TypeError(&quot;handler &#x5FC5;&#x987B;&#x4E3A;&#x4E8B;&#x4EF6;&#x5904;&#x7406;&#x51FD;&#x6570;(function)&#x6216;&#x8005;&#x662F;&#x4E8B;&#x4EF6;&#x4FA6;&#x542C;&#x5668;(IEventListener)&#x3002;&quot;); } const listener = new EventListener(handler, options); /** * &#x5728;&#x4E8B;&#x4EF6;&#x6D3E;&#x53D1;&#x8FC7;&#x7A0B;&#x4E2D;&#x4FEE;&#x6539;&#x4FA6;&#x542C;&#x5668;&#x5217;&#x8868;&#x4F1A;&#x5BFC;&#x81F4;&#x6D3E;&#x53D1;&#x987A;&#x5E8F;&#x9519;&#x8BEF;&#xFF0C;&#x56E0;&#x6B64;&#x8FD9;&#x91CC;&#x9700;&#x8981;&#x62F7;&#x8D1D;&#x4FA6;&#x542C;&#x5668;&#x5217;&#x8868;&#x7684;&#x526F;&#x672C;&#x3002; * * @example * const dispatcher = new EventDispatcher(); * dispatcher.addEventListener(&quot;custom&quot;, () =&gt; { // &#x5982;&#x679C;&#x4E0D;&#x9501;&#x5B9A;&#x4FA6;&#x542C;&#x5668;&#x5217;&#x8868;&#x7684;&#x5316;&#xFF0C;&#x8FD9;&#x91CC;&#x5C06;&#x4EA7;&#x751F;&#x4E00;&#x4E2A;&#x6B7B;&#x5FAA;&#x73AF;&#x3002; * console.log(1}; * dispatcher.addEventListener(&quot;custom&quot;, () =&gt; {}, { &quot;priority&quot;: 1 }); * }); * dispatcher.dispatchEvent(new Event(&quot;custom&quot;, false, false)); */ if ( this._listenerLockers[type] ) { this._listenerLockers[type] = false; this._listenerRegister[type] = this._listenerRegister[type].slice(0); } /// &#x79FB;&#x9664;&#x91CD;&#x590D;&#x7684;&#x4E8B;&#x4EF6;&#x4FA6;&#x542C;&#x5668;&#x3002; this.removeEventListener(type, handler, listener.options.useCapture); /// &#x6CA1;&#x6709;&#x4E3A; type &#x7C7B;&#x578B;&#x7684;&#x4E8B;&#x4EF6;&#x6CE8;&#x518C;&#x4FA6;&#x542C;&#x5668;&#x3002; if ( !this.hasEventListener(type) ) { this._listenerRegister[type] = [listener]; return; } /// &#x4E3A; type &#x7C7B;&#x578B;&#x5DF2;&#x7ECF;&#x6CE8;&#x518C;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x5217;&#x8868;&#x3002; const items = this._listenerRegister[type]; /** * &#x4E00;&#x822C;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x6211;&#x4EEC;&#x6CE8;&#x518C;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x90FD;&#x662F;&#x9ED8;&#x8BA4;&#x7684; 0&#x3002;&#x56E0;&#x6B64;&#x8FD9;&#x91CC;&#x53EF;&#x4EE5;&#x5148;&#x5BF9;&#x6BD4;&#x63D2;&#x5165;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x662F;&#x5426;&#x4E3A;&#x6700;&#x4F4E;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x3002; * &#x5982;&#x679C;&#x662F;&#x5219;&#x76F4;&#x63A5;&#x653E;&#x5165;&#x5217;&#x8868;&#x672B;&#x5C3E;&#x3002;&#x4ECE;&#x800C;&#x51CF;&#x5C11;&#x4E3A;&#x63D2;&#x5165;&#x4FA6;&#x542C;&#x5668;&#x800C;&#x904D;&#x5386;&#x5217;&#x8868;&#x7684;&#x6B21;&#x6570;&#x3002; */ if ( items[items.length - 1].options.priority &gt;= listener.options.priority ) { items.push(listener); return; } /** * &#x6309;&#x7167;&#x4FA6;&#x542C;&#x5668;&#x6CE8;&#x518C;&#x7684;&#x987A;&#x5E8F;&#x4EE5;&#x53CA;&#x4FA6;&#x542C;&#x5668;&#x4F18;&#x5148;&#x7EA7;&#x7684;&#x5927;&#x5C0F;&#x63D2;&#x5165;&#x5217;&#x8868;&#x3002; * - 1, &#x4F18;&#x5148;&#x8D8A;&#x9AD8;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x653E;&#x5230;&#x5217;&#x8868;&#x7684;&#x524D;&#x9762;&#x3002; * - 2, &#x76F8;&#x540C;&#x4F18;&#x5148;&#x7EA7;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x5148;&#x6CE8;&#x518C;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x653E;&#x5230;&#x5217;&#x8868;&#x7684;&#x524D;&#x9762;&#x3002; */ let insertAt = items.length - 1; while( ((insertAt &gt;= 0) &amp;&amp; (items[insertAt].options.priority &lt; listener.options.priority)) ) { --insertAt; } items.splice(1 + insertAt, 0, listener); } /** * &#x79FB;&#x9664;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x4FA6;&#x542C;&#x5668;&#x3002; * * &#x7B2C;&#x4E09;&#x4E2A;&#x53C2;&#x6570; `useCapture` &#x53EF;&#x4EE5;&#x662F;&#x4E00;&#x4E2A; {@link Boolean} &#x7C7B;&#x578B;&#x7684;&#x503C;&#xFF0C;&#x6216;&#x8005;&#x662F;&#x4E00;&#x4E2A; {@link IEventListenerOptions} &#x7C7B;&#x578B;&#x7684;&#x503C;&#x3002; * * &#x53EA;&#x6709;&#x5B8C;&#x5168;&#x76F8;&#x540C;&#xFF08;&#x4F7F;&#x7528; === &#x5BF9;&#x6BD4;&#xFF09;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x624D;&#x4F1A;&#x88AB;&#x79FB;&#x9664;&#x3002;&#x56E0;&#x6B64;&#x4F7F;&#x7528; `useCapture=false` &#x5E76;&#x4E0D;&#x4F1A;&#x79FB;&#x9664;**&#x6355;&#x83B7;&#x9636;&#x6BB5;**&#x7684;&#x4FA6;&#x542C;&#x5668;&#x3002; * &#x540C;&#x7406; `useCapture=true` &#x4E5F;&#x4E0D;&#x4F1A;&#x79FB;&#x9664;**&#x5192;&#x6CE1;&#x9636;&#x6BB5;**&#x7684;&#x4FA6;&#x542C;&#x5668;&#x3002; * * @param {String|Symbol} type - &#x4E8B;&#x4EF6;&#x7C7B;&#x578B;&#x3002; * @param {Function|IEventListener} handler - &#x6307;&#x5B9A;&#x8981;&#x79FB;&#x9664;&#x7684;&#x4E8B;&#x4EF6;&#x5904;&#x7406;&#x51FD;&#x6570;&#x6216;&#x8005;&#x4E8B;&#x4EF6;&#x4FA6;&#x542C;&#x5668;&#x3002; * @param {Boolean|IEventListenerOptions} [useCapture=false] - &#x6307;&#x5B9A;&#x662F;&#x79FB;&#x9664;&#x6355;&#x83B7;&#x9636;&#x6BB5;(`true`)&#x8FD8;&#x662F;&#x5192;&#x6CE1;&#x9636;&#x6BB5;(`false`)&#x7684;&#x4E8B;&#x4EF6;&#x4FA6;&#x542C;&#x5668;&#x3002; * @example * /// &#x4F7F;&#x7528;&#x4E0D;&#x7528;&#x7C7B;&#x578B;&#x7684; useCapture &#x503C;&#x79FB;&#x9664;&#x4FA6;&#x542C;&#x5668;&#x3002; * dispatcher.removeEventListener(type, handler, false); * dispatcher.removeEventListener(type, handler, { &quot;useCapture&quot;: true }); * * /// &#x5206;&#x522B;&#x79FB;&#x9664;&#x4E0D;&#x7528;&#x9636;&#x6BB5;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x3002; * const dispatcher = new EventDispatcher(); * * function captureHandler( evt ) { * console.log(&quot;capture&quot;); * } * * dispatcher.addEventListener(&quot;custom&quot;, captureHandler, true); * dispatcher.removeEventListener(&quot;custom&quot;, captureHandler, false); // &#x8FD9;&#x91CC;&#x5E76;&#x4E0D;&#x4F1A;&#x79FB;&#x9664; captureHandler &#x4FA6;&#x542C;&#x5668;&#x3002; * dispatcher.hasEventListener(&quot;custom&quot;); // true * dispatcher.removeEventListener(&quot;custom&quot;, captureHandler, true); // &#x8FD9;&#x91CC;&#x624D;&#x4F1A;&#x79FB;&#x9664; captureHandler &#x4FA6;&#x542C;&#x5668;&#x3002; * dispatcher.hasEventListener(&quot;custom&quot;); // false * @since 1.0.0 */ removeEventListener( type, handler, useCapture = false ) { if ( !this.hasEventListener(type) ) { return; } /** * &#x5982;&#x679C; `useCapture` &#x662F;&#x4E00;&#x4E2A; {@link IEventListenerOptions} &#x5BF9;&#x8C61;&#xFF0C;&#x5219;&#x83B7;&#x53D6; `IEventListenerOptions.useCapture` &#x7684;&#x503C;&#x3002; */ if ( typeof useCapture != &quot;boolean&quot; ) { /** @type {IEventListenerOptions} */ const options = useCapture; useCapture = (options.useCapture !== void 0 ? options.useCapture : false); } /** * &#x5728;&#x4E8B;&#x4EF6;&#x6D3E;&#x53D1;&#x8FC7;&#x7A0B;&#x4E2D;&#x4FEE;&#x6539;&#x4FA6;&#x542C;&#x5668;&#x5217;&#x8868;&#x4F1A;&#x5BFC;&#x81F4;&#x6D3E;&#x53D1;&#x987A;&#x5E8F;&#x9519;&#x8BEF;&#xFF0C;&#x56E0;&#x6B64;&#x8FD9;&#x91CC;&#x9700;&#x8981;&#x62F7;&#x8D1D;&#x4FA6;&#x542C;&#x5668;&#x5217;&#x8868;&#x7684;&#x526F;&#x672C;&#x3002; * @see {@link EventDispatcher#addEventListener} */ if ( this._listenerLockers[type] ) { this._listenerLockers[type] = false; this._listenerRegister[type] = this._listenerRegister[type].slice(0); } for ( let i = 0, items = this._listenerRegister[type]; i &lt; items.length; ++i ) { /** * &#x53EA;&#x6709;&#x5B8C;&#x5168;&#x76F8;&#x540C;&#xFF08;&#x4F7F;&#x7528; === &#x5BF9;&#x6BD4;&#xFF09;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x624D;&#x4F1A;&#x88AB;&#x79FB;&#x9664;&#x3002; */ if ( handler === items[i].handler &amp;&amp; useCapture === items[i].options.useCapture ) { items.splice(i, 1); break; } } } /** * &#x68C0;&#x67E5;&#x662F;&#x5426;&#x6CE8;&#x518C;&#x4E86;&#x6307;&#x5B9A;&#x7C7B;&#x578B;&#x7684;&#x4E8B;&#x4EF6;&#x4FA6;&#x542C;&#x5668;&#x3002; * @param {String|Symbol} type - &#x4E8B;&#x4EF6;&#x7C7B;&#x578B;&#x3002; * @example * const dispatcher = new EventDispatcher(); * dispatcher.addEventListener(&quot;custom&quot;, ( evt ) =&gt; {}, false); * * console.log(dispatcher.hasEventListener(&quot;custom&quot;)); // true * console.log(dispatcher.hasEventListener(&quot;notexists&quot;)); // false * @returns {Boolean} - &#x5982;&#x679C;&#x5B58;&#x5728;&#x6307;&#x5B9A;&#x7C7B;&#x578B;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x5219;&#x8FD4;&#x56DE; `true`&#xFF0C;&#x5426;&#x5219;&#x8FD4;&#x56DE; `false`&#x3002; * @since 1.0.0 */ hasEventListener( type ) { return (!!this._listenerRegister[type] &amp;&amp; this._listenerRegister[type].length &gt;= 1); } /** * &#x6D3E;&#x53D1;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x5BF9;&#x8C61;&#x5230;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x7684;&#x4E8B;&#x4EF6;&#x6D41;&#x4E2D;&#x3002; * @param {Event|String|Symbol} event - &#x6307;&#x5B9A;&#x6D3E;&#x53D1;&#x7684;&#x4E8B;&#x4EF6;&#x5BF9;&#x8C61;&#x3002; * @example * const dispatcher = new EventDispatcher(); * * dispatcher.dispatchEvent(new Event(&quot;custom&quot;, false, false)); // &#x6D3E;&#x53D1;&#x4E00;&#x4E2A;&#x4E0D;&#x5192;&#x6CE1;&#x7684;&#x4E8B;&#x4EF6;&#x3002; * dispatcher.dispatchEvent(new Event(&quot;custom&quot;, true, false)); // &#x6D3E;&#x53D1;&#x4E00;&#x4E2A;&#x53C2;&#x4E0E;&#x5192;&#x6CE1;&#x7684;&#x4E8B;&#x4EF6;&#x3002; * @returns {Boolean} - &#x5982;&#x679C;&#x4E8B;&#x4EF6;&#x4F20;&#x9012;&#x5230;&#x4E86;&#x5F53;&#x524D;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#xFF0C;&#x5E76;&#x4E14;&#x6CA1;&#x6709;&#x88AB;&#x53D6;&#x6D88;&#x9ED8;&#x8BA4;&#x884C;&#x4E3A;&#x3002;&#x5219;&#x8FD4;&#x56DE; `true`&#xFF0C;&#x5426;&#x5219;&#x8FD4;&#x56DE; `false`&#x3002; * @since 1.0.0 */ dispatchEvent( event ) { if ( typeof event == &quot;string&quot; || typeof event == &quot;symbol&quot; ) { event = new Event(event); } /// &#x8BE5;&#x4E8B;&#x4EF6;&#x5BF9;&#x8C61;&#x5DF2;&#x7ECF;&#x88AB;&#x6D3E;&#x53D1;&#x8FC7;&#x4E00;&#x6B21;&#xFF01; if ( event.target || event.eventPhase !== EventPhase.NONE ) { throw new Error(&quot;&#x540C;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x5BF9;&#x8C61;&#x4E0D;&#x80FD;&#x6D3E;&#x53D1;&#x591A;&#x6B21;&#xFF01;&quot;); } event._target = this._targetDispatcher; // &#x8BBE;&#x7F6E;&#x4E8B;&#x4EF6;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x3002; /** * &#x6EE1;&#x8DB3;&#x4EE5;&#x4E0B;&#x6761;&#x4EF6;&#x65F6;&#xFF0C;&#x76F4;&#x63A5;&#x8C03;&#x5EA6;&#x4E8B;&#x4EF6;&#x81F3;&#x76EE;&#x6807;&#x9636;&#x6BB5;&#xFF1A; * * 1) &#x4E8B;&#x4EF6;&#x4E0D;&#x53C2;&#x4E0E;&#x5192;&#x6CE1;&#x884C;&#x4E3A;&#x3002; * 2) &#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x6CA1;&#x6709;&#x52A0;&#x5165;&#x663E;&#x793A;&#x5BF9;&#x8C61;&#x5217;&#x8868;&#x3002; */ if ( !event.bubbles || !event.target.parent /*&lt; &#x9632;&#x6B62;&#x6839;&#x7EA7;&#x522B;&#x5BF9;&#x8C61;&#x5FAA;&#x73AF;&#x5F15;&#x7528; &gt;*/ || (event.target === event.target.parent) ) { event._eventPhase = EventPhase.AT_TARGET; event._currentTarget = event.target; if ( event.currentTarget._dispatchToListeners ) { event.currentTarget._dispatchToListeners(event); } event._currentTarget = null; // &#x4E8B;&#x4EF6;&#x6D3E;&#x53D1;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x5220;&#x9664;&#x4E8B;&#x4EF6;&#x5BF9;&#x5F53;&#x524D;&#x76EE;&#x6807;&#x7684;&#x5F15;&#x7528;&#x3002; return !event.defaultPrevented; } /** * &#x67E5;&#x627E;&#x4E8B;&#x4EF6;&#x4F20;&#x9012;&#x8DEF;&#x5F84;&#x3002; */ let target = event.target; let path = [target]; while( target.parent &amp;&amp; target !== target.parent ) { path.push(target = target.parent); } /** * &#x6355;&#x83B7;&#x9636;&#x6BB5;&#x3002; */ event._eventPhase = EventPhase.CAPTURING_PHASE; for ( let i = path.length - 1; i &gt;= 1 &amp;&amp; !event._stopPropagation; --i ) { event._currentTarget = path[i]; if ( event.currentTarget._dispatchToListeners ) { event.currentTarget._dispatchToListeners(event); } } if ( event._stopPropagation ) { // &#x4E8B;&#x4EF6;&#x5728;&#x6355;&#x83B7;&#x9636;&#x6BB5;&#x88AB;&#x4E2D;&#x65AD;&#x3002; event._currentTarget = null; return false; } /** * &#x76EE;&#x6807;&#x9636;&#x6BB5;&#x3002; */ event._eventPhase = EventPhase.AT_TARGET; event._currentTarget = path[0]; if ( event.currentTarget._dispatchToListeners ) { event.currentTarget._dispatchToListeners(event); } if ( event._stopPropagation ) { event._currentTarget = null; return !event.defaultPrevented; } /** * &#x5192;&#x6CE1;&#x9636;&#x6BB5;&#x3002; */ event._eventPhase = EventPhase.BUBBLING_PHASE; for ( let i = 1; i &lt; path.length &amp;&amp; !event._stopPropagation; ++i ) { event._currentTarget = path[i]; if ( event.currentTarget._dispatchToListeners ) { event.currentTarget._dispatchToListeners(event); } } event._currentTarget = null; return !event.defaultPrevented; } /** * &#x6267;&#x884C;&#x6240;&#x6709;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x3002; * @param {Event} event - &#x6307;&#x5B9A;&#x6D3E;&#x53D1;&#x7684;&#x4E8B;&#x4EF6;&#x5BF9;&#x8C61;&#x3002; */ _dispatchToListeners( event ) { if ( !this.hasEventListener(event.type) ) { return; } /** * &#x9501;&#x5B9A;&#x4FA6;&#x542C;&#x5668;&#x5217;&#x8868;&#x3002; */ this._listenerLockers[event.type] = true; /** * &#x6267;&#x884C;&#x4FA6;&#x542C;&#x5668; */ for ( let i = 0, items = this._listenerRegister[event.type]; i &lt; items.length &amp;&amp; !event._stopImmediatePropagation; ++i ) { /** @type {EventListener} */ const listener = items[i]; switch( event.eventPhase ) { case EventPhase.CAPTURING_PHASE : if ( listener.options.useCapture ) { listener.handleEvent(event); } break; case EventPhase.AT_TARGET : listener.handleEvent(event); break; case EventPhase.BUBBLING_PHASE : if ( !listener.options.useCapture ) { listener.handleEvent(event); } break; default: break; } /** * &#x81EA;&#x52A8;&#x79FB;&#x9664;&#x4E00;&#x6B21;&#x6027;&#x7684;&#x4FA6;&#x542C;&#x5668;&#x3002; */ if ( listener.options.once ) { this.removeEventListener(event.type, listener.handler, listener.options.useCapture); } } /** * &#x89E3;&#x9501;&#x4FA6;&#x542C;&#x5668;&#x5217;&#x8868;&#x3002; */ this._listenerLockers[event.type] = false; } }</code></pre> </div> <footer class="footer"> Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.0.4)</span><img src="./image/esdoc-logo-mini-black.png"></a> </footer> <script src="script/search_index.js"></script> <script src="script/search.js"></script> <script src="script/pretty-print.js"></script> <script src="script/inherited-summary.js"></script> <script src="script/test-summary.js"></script> <script src="script/inner-link.js"></script> <script src="script/patch-for-local.js"></script> </body> </html>