搜尋

首頁  >  問答  >  主體

javascript - jQuery问题:在click()方法中使用this

jQ版本:jquery-1.7.2.js

HTML:
    <p id="box">test</p>
JS:
<script>
    $(function(){ 
        $('#box').click(function(){ 
            //alert(this.html()); // 报错
            alert(this.innerHTML);// test
            alert($(this).html()); // test
        });    
    });
</script>    

请问一下,经$('#box')获取后,已经得到jQuery对象了,为什么this对应的还是DOM对象,而$(this)却是jQuery对象呢?谢谢!

伊谢尔伦伊谢尔伦2822 天前791

全部回覆(8)我來回復

  • PHPz

    PHPz2017-04-10 16:08:35

    this引用的是函数执行的环境对象,比如在全局中调用,this就是window。所以你这个this并不是$("#box")返回的,不是JQ对象,而是调用此函数的p这个dom对象。仔细理解下this。
    手机打字好费劲,如果还有不明白的明天开电脑说

    评论中的补充:


    $('#box')已经返回JQuery对象了啊,所以你后面才能调用click()方法,注意你这一步相当于

    var $box = $('#box');
    $box.click(function(){
        //TODO
    });

    而函数执行的环境对象跟你这句代码获得什么对象没关系,本质是在这个DOM上绑定一个事件,
    事件触发时,this就只是这个DOM


    $(this)并不会改变这个DOM对象,只是进行了一次包装,就像是加了一层外壳,让他变成JQuery对象,从而能够使用JQuery方法,并不是像传入选择器一样去寻找DOM,因此它仍是当前触发此事件的p.box。包装后的JQuery可以还原成DOM对象。
    看看下面的代码,通过事件对象获取触发事件的对象:

    $('.box').click(function(event){
        console.log(event.target);
        console.log(event.target==this);//非事件冒泡情况下为true
        console.log($(this).get(0)==this);//true
    });

    回覆
    0
  • 黄舟

    黄舟2017-04-10 16:08:35

    你要知道没有jquery 也有js,没有js就没有jquery。 this 是js的东东,函数执行环境中的this 是属于原生js的,怎么能够给你指向jquery对象。 穿上$(this)马甲 才是jquery对象。

    回覆
    0
  • 迷茫

    迷茫2017-04-10 16:08:35

    这个this是callback中的this,又不是click中的this。所以和$('#box')没关系,具体指什么是取决于click()中这个callback的上下文环境(在这里是调用这个callback的DOM节点,也就是你用document.getElement方法返回的那个)。

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-10 16:08:35

    简单点,按照下面方式来理解这段代码: $('#box').click(fn)

    1. $('#box')获得的是一个类数组(虽然现在数组中只有一个元素),可模拟成:

    var obj = {length:1,"0":domEle}  //其中domEle是id为box的的dom元素.
    1. $('#box').click(fn)做了什么事情呢?其实就相当于:

     for(var i =0;i<obj.length;i++) {
       fn.apply(obj[i],arguments);  //obj[i]不就是一个dom元素么?与$('#box')也就是obj什么关系都没
     }

    当然,jquery中具体的处理很复杂,上面的代码只是模拟,便于你理解罢了!

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-10 16:08:35

    先谢谢各位的热心帮助。看过各位的回答后,我有一些新的认识(不知道对不对)。
    1.传入click方法中的是一个回调函数,所以this不是$('#box')。
    2.有个问题:回调函数中的this,如果放到js中,应该是指向window吧?为什么在jQ中会指向当前的DOM元素呢?

    <body>

    <input type="button" value="点击" />

    <script>

    window.onload=function(){ 
        var oBtn=document.body.children[0];
        oBtn.onclick=function(){ 
            (function(){ 
                alert(this); //window
            })()
        };
    };

    </script>
    </body>

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-10 16:08:35

    1. 函数中的this到底指向的什么样的对象,取决于执行上下文的环境

    2. 函数中的this可以通过apply/call/bind等函数方法人为的改变

    3. $('#box').click 方法是jQuery的自定义方法,不是原生的

    4. click回调函数中的this到底指向什么就取决于jQuery对click函数的定义了。换句话说,在实现的时候可以指向DOM元素,也可以指向包装DOM对象后的jQuery对象

    5. 具体指向什么对象,需要参考API说明文档了,(某天可能改为指向jQuery对象了呢:))

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-10 16:08:35

    jQuery 源码

        dispatch: function( event ) {
    
            // Make a writable jQuery.Event from the native event object
            event = jQuery.event.fix( event );
    
            var i, ret, handleObj, matched, j,
                handlerQueue = [],
                args = slice.call( arguments ),
                handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
                special = jQuery.event.special[ event.type ] || {};
    
            // Use the fix-ed jQuery.Event rather than the (read-only) native event
            args[0] = event;
            event.delegateTarget = this;
    
            // Call the preDispatch hook for the mapped type, and let it bail if desired
            if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
                return;
            }
    
            // Determine handlers
            handlerQueue = jQuery.event.handlers.call( this, event, handlers );
    
            // Run delegates first; they may want to stop propagation beneath us
            i = 0;
            while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
                event.currentTarget = matched.elem;
    
                j = 0;
                while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
    
                    // Triggered event must either 1) have no namespace, or
                    // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
                    if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
    
                        event.handleObj = handleObj;
                        event.data = handleObj.data;
    
                        ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
                                .apply( matched.elem, args );
    
                        if ( ret !== undefined ) {
                            if ( (event.result = ret) === false ) {
                                event.preventDefault();
                                event.stopPropagation();
                            }
                        }
                    }
                }
            }
    
            // Call the postDispatch hook for the mapped type
            if ( special.postDispatch ) {
                special.postDispatch.call( this, event );
            }
    
            return event.result;
        }

    注意看这一段

    ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ).apply( matched.elem, args )
    

    楼主代码当中的click里的回调函数就是在这个时候以apply的方式调用的。
    matched.elem就是原生DOM对象。作为回调函数的context,也就是回调函数当中的this
    jQuery 就是这么实现的。

    回覆
    0
  • 怪我咯

    怪我咯2017-04-10 16:08:35

    不管是不是 this, $(xxx) 返回的都是jQuery对象

    因为 $(xxx) = jQuery(xxx),如果没有使用 noConflict 的情况下。

    回覆
    0
  • 取消回覆