>  기사  >  웹 프론트엔드  >  yourself_jquery가 작성한 jQuery 콜백의 전체 기능 코드에 대한 자세한 설명

yourself_jquery가 작성한 jQuery 콜백의 전체 기능 코드에 대한 자세한 설명

WBOY
WBOY원래의
2016-05-16 17:12:35767검색

사용법은 $.Callbacks와 완전히 동일하지만 매개 변수가 있는 추가, 제거, 실행, 비어 있음, 생성자 함수만 구현합니다. $.Callbacks에는 비활성화, 비활성화, fireWith, 실행, 잠금, 잠김 메서드도 있습니다.

코드는 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.

 String.prototype.trim = function ()
        {
            return this.replace( /^\s+|\s+$/g, '' );
        };

        // Simulate jQuery.Callbacks object
        function MyCallbacks( options )
        {
            var ops = { once: false, memory: false, unique: false, stopOnFalse: false };

            if ( typeof options === 'string' && options.trim() !== '' )
            {
                var opsArray = options.split( /\s+/ );
                for ( var i = 0; i < options.length; i++ )
{
if ( opsArray[i] === 'once' )
ops.once = true;
else if ( opsArray[i] === 'memory' )
ops.memory = true;
else if ( opsArray[i] === 'unique' )
ops.unique = true;
else if ( opsArray[i] === 'stopOnFalse' )
ops.stopOnFalse = true;
}
}

var ar = [];
var lastArgs = null;
var firedTimes = 0;

function hasName( name )
{
var h = false;

if ( typeof name === 'string'
&& name !== null
&& name.trim() !== ''
&& ar.length > 0 )
                {
                    for ( var i = 0; i < ar.length; i++ )
{
if ( ar[i].name === name )
{
h = true;
break;
}
}
}

return h;
}

// add a function
this.add = function ( fn )
{
if ( typeof fn === 'function' )
{
if ( ops.unique )
{
// check whether it had been added before
if ( fn.name !== '' && hasName( fn.name ) )
{
return this;
}
}

ar.push( fn );

if ( ops.memory )
{
// after added , call it immediately
fn.call( this, lastArgs );
}
}

return this;
};

// remove a function
this.remove = function ( fn )
{
if ( typeof ( fn ) === 'function'
&& fn.name !== ''
&& ar.length > 0 )
                {
                    for ( var i = 0; i < ar.length; i++ )
{
if ( ar[i].name === fn.name )
{
ar.splice( i, 1 );
}
}
}

return this;
};

// remove all functions
this.empty = function ()
{
ar.length = 0;
return this;
};

// check whether it includes a specific function
this.has = function ( fn )
{
var f = false;

if ( typeof ( fn ) === 'function'
&& fn.name !== ''
&& ar.length > 0 )
                {
                    for ( var i = 0; i < ar.length; i++ )
{
if ( ar[i].name === fn.name )
{
f = true;
break;
}
}
}

                반환 f;
            };

            // 포함된 함수를 하나씩 호출
            this.fire = function ( args )
            {
               if ( ops.once && FireTimes > 0 )
                {
                   이것을 반환 ;
                }

               if (ar.length > 0 )
                {
                  var r;

                   for ( var i = 0; i < ar.length; i )
                  {
                      r = ar[i].call( this, args );

                      if ( ops.stopOnFalse && r === false )
                    {
                         break;
                       }
                   }
               }

                FireTimes ;

               if ( ops.memory )
               {
                  lastArgs = args;
                }

               이것을 반품하세요.
            };
        };
 

 测试函数如下:(注意fn1 fn2是匿name函数, fn2返回false, fn3是유“명”函数)

 

复主代码 代码如下:

 var fn1 = 함수( v )
        {
            console.log( 'fn1 ' ( v || '' ) );
        };

        var fn2 = 함수 ( v )
        {
            console.log( 'fn2 ' ( v || '' ) );
            return false;
        };

        기능 fn3( v )
        {
            console.log( 'fn3 ' ( v || '' ) );
       };
 

1. 테스트 추가 및 실행

var cb=new MyCallbacks();

cb.add(fn1)

cb.add(fn2)

cb.add(fn3)

cb.fire('안녕하세요')

출력:

fn1 안녕하세요
fn2 안녕하세요
fn3 안녕하세요

2. 테스트 제거
var cb=new MyCallbacks();

cb.add(fn1)

cb.add(fn2)

cb.add(fn3)

cb.remove(fn1)
cb.fire('hello')
cb.remove(fn3)
cb.fire('hello')
출력:

fn1 안녕하세요
fn2 안녕하세요
fn3 안녕하세요
-------------------------------- --
fn1 안녕하세요
fn2 안녕하세요

2. 테스트에는
var cb=new MyCallbacks();

가 있습니다.

cb.add(fn1)

cb.add(fn2)

cb.add(fn3)

cb.has(fn1)

cb.has(fn3)

출력:

거짓

---------------

그렇습니다

3. 매개변수를 사용하여 생성자를 테스트합니다: 한 번

var cb=new MyCallbacks('한 번')

cb.add(fn1)

cb.fire('안녕하세요')

cb.fire('안녕하세요')

cb.add(fn2)

cb.fire('안녕하세요')

출력:

안녕하세요

------

------

------------------

4. 매개변수를 사용하여 생성자를 테스트합니다: 메모리

var cb=new MyCallbacks('memory')

cb.add(fn1)

cb.fire('hello') // 출력: fn1 hello

cb.add(fn2) // 출력: fn2 hello

cb.fire('안녕하세요')

출력:

fn1 안녕하세요

fn2 안녕하세요

5. 매개변수를 사용하여 생성자를 테스트합니다: stopOnFalse

var cb=new MyCallbacks('stopOnFalse')

cb.add(fn1)

cb.add(fn2)

cb.add(fn3)

cb.fire('안녕하세요')

출력:

fn1 hello
fn2 hello
6. 고유 매개변수를 사용하여 생성자를 테스트합니다

var cb=new MyCallbacks('unique')

b.추가(fn3)

b.추가(fn3)

cb.fire('안녕하세요')

출력:

fn3 안녕하세요

7. 결합된 매개변수로 생성자를 테스트합니다. 4개의 설정 매개변수를 마음대로 결합할 수 있습니다. 모든 조합을 한 번에 테스트해야 합니다. 그렇지 않으면 16개의 테스트 사례를 작성해야 합니다.

var cb=new MyCallbacks('일회 메모리 고유 stopOnFalse')

cb.add(fn1) // 출력: fn1

cb.add(fn2) // 출력: fn2

cb.add(fn3) // 출력: fn3

cb.fire('안녕하세요')

출력:

fn1 hello

fn2 hello
cb.fire('hello') // 출력: 출력 없음

공식 API 문서는 다음과 같습니다.

설명: 콜백 목록을 관리하는 강력한 방법을 제공하는 다목적 콜백 목록 개체입니다. $.Callbacks() 함수는 내부적으로 jQuery $.ajax() 및 $.Deferred(의 기본 기능을 제공하는 데 사용됩니다. ) 구성요소는 새로운 구성요소의 기능을 정의하기 위한 유사한 기반으로 사용될 수 있습니다.

생성자: jQuery.Callbacks( 플래그 )

flags

유형: 문자열
콜백 목록의 작동 방식을 변경하는 공백으로 구분된 플래그의 선택적 목록입니다.
가능한 플래그:
once: 콜백 목록이 한 번만 실행될 수 있도록 보장합니다( Deferred와 같음).
memory: 이전 값을 추적하고 목록이 실행된 후 추가된 모든 콜백을 최신 "기억된" 값(예: Deferred)으로 즉시 호출합니다.
고유 : 콜백을 한 번만 추가할 수 있도록 합니다(목록에 중복이 없도록 합니다).
stopOnFalse: 콜백이 false를 반환할 때 호출을 중단합니다.
기본적으로 콜백 목록은 이벤트 콜백 목록처럼 작동하며 다음을 수행할 수 있습니다. 여러 번 "해고"당했습니다.

위에서는 .add() 및 .fire()라는 두 가지 특정 메서드가 사용되었습니다. .add() 메서드는 콜백 목록에 새 콜백을 추가하는 것을 지원하는 반면, .fire() 메서드는 추가된 함수를 실행하고 동일한 목록의 콜백에서 처리할 인수를 전달하는 방법입니다.

콜백을 사용하여 게시-구독 모드 게시/구독 구현: (공식 문서)

코드 복사 코드는 다음과 같습니다.

var 주제 = {};

        jQuery.Topic = 함수( id )
        {
            var 콜백,
               메소드,
               주제 = id && 주제[id];

            if ( !topic )
            {
               콜백 = jQuery.Callbacks();
              주제 = {
                  게시: callbacks.fire,
                    구독: callbacks.add,
구독 취소: callbacks.remove
               };
               if ( id )
               {
                   주제[id] = 주제;
                }
            }
            주제 반환;
        };

사용

复主代码 代码如下:

$.Topic( 'mailArrived' ).subscribe( function ( e )
        {
            console.log( '새 이메일이 있습니다! ' );
            console.log( "메일 제목 : " e.title );
            console.log( "메일 내용 : " e.content );
        }
        );

        $.Topic( 'mailArrived' ).publish( { title: 'mail title', content: 'mail content' } );

<…入了匿name函数内, 然后通过工厂方法 window.callbacks 返回实例, 以免每次使用必须 new .


具体代码如下, 有兴趣和时间的可以对PhotojQuery특별콜백对比下 :

复主代码 代码如下:

( function ( window, undefined )
{
// Simulate jQuery.Callbacks object
function Callbacks( options )
{
var ops = { once: false, memory: false, unique: false, stopOnFalse: false },
ar = [],
lastArgs = null,
firedTimes = 0,
_disabled = false,
_locked = false;

if ( typeof options === 'string' && options.trim() !== '' )
{
var opsArray = options.split( /\s+/ );
for ( var i = 0; i < options.length; i++ )
{
if ( opsArray[i] === 'once' )
ops.once = true;
else if ( opsArray[i] === 'memory' )
ops.memory = true;
else if ( opsArray[i] === 'unique' )
ops.unique = true;
else if ( opsArray[i] === 'stopOnFalse' )
ops.stopOnFalse = true;
}
}

function hasName( name )
{
var h = false;

if ( typeof name === 'string'
&& name !== null
&& name.trim() !== ''
&& ar.length > 0 )
                    {
                        for ( var i = 0; i < ar.length; i++ )
{
if ( ar[i].name === name )
{
h = true;
break;
}
}
}

return h;
}

// add a function
this.add = function ( fn )
{
if ( typeof fn === 'function' )
{
if ( ops.unique )
{
// check whether it had been added before
if ( fn.name !== '' && hasName( fn.name ) )
{
return this;
}
}

ar.push( fn );

if ( ops.memory )
{
// after added , call it immediately
fn.call( this, lastArgs );
}
}

return this;
};

// remove a function
this.remove = function ( fn )
{
if ( typeof ( fn ) === 'function'
&& fn.name !== ''
&& ar.length > 0 )
                    {
                        for ( var i = 0; i < ar.length; i++ )
{
if ( ar[i].name === fn.name )
{
ar.splice( i, 1 );
}
}
}

return this;
};

// remove all functions
this.empty = function ()
{
ar.length = 0;
return this;
};

// check whether it includes a specific function
this.has = function ( fn )
{
var f = false;

if ( typeof ( fn ) === 'function'
&& fn.name !== ''
&& ar.length > 0 )
                    {
                        for ( var i = 0; i < ar.length; i++ )
{
if ( ar[i].name === fn.name )
{
f = true;
break;
}
}
}

return f;
};

this.disable = function ()
{
_disabled = true;
return this;
};

this.disabled = function ()
{
return _disabled;
};

this.fired = function ()
{
return firedTimes > 0;
                };

                function _fire( context, args )
                {
                    if ( _disabled || ops.once && firedTimes > 0 || _locked )
                    {
                        return;
                    }

                    if ( ar.length > 0 )
                    {
                        var r;

                        for ( var i = 0; i < ar.length; i++ )
                        {
                            r = ar[i].call( context, args );

                            if ( ops.stopOnFalse && r === false )
                            {
                                break;
                            }
                        }
                    }

                    firedTimes++;

                    if ( ops.memory )
                    {
                        lastArgs = args;
                    }

                };

                this.fireWith = function ( context, args )
                {
                    context = context || this;
                    _fire( context, args );
                    return this;
                };

                this.fire = function ( args )
                {
                    _fire( this, args );
                    return this;
                };

                this.lock = function ()
                {
                    _locked = true;
                    return this;
                };

               this.locked = function ()
                {
                  return _locked;
               };

            };

            // 팩토리 메서드로 전역에 노출
            window.callbacks = function ( options )
            {
               새 콜백 반환( options );
           };

        } )( 창 );

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.