jquery parents方法的一些困惑

項目中有一個邏輯是這樣的: 對當前元素的外層<li>元素進行操做, 個人作法是這樣的:$(someElement.parents('li')).xxxjavascript

因爲當前元素外層只有一個li元素,當時就沒有多想,後來仔細查看parents(selector)方法的說明,發現調用這個方法以後會返回全部匹配selector的元素;html

按理說,返回值應該是一個數組或者相似數組的結構猜對,而在這種結構上調用單個元素的方法(好比attr('id'))感受上應該報錯纔對;java

而後作了以下實驗:jquery

<!DOCTYPE html>
<html>
<head>
  <style>
  b, span, p, html body {
    padding: .5em;
    border: 1px solid;
  }
  b { color:blue; }
  strong { color:red; }
  </style>
  <script type="text/javascript" src="/jquery/jquery.js"></script>
</head>

<body>
  <div id="div1">
    <p>
     <div id='div2'>
      <span>
            <b>個人父元素是:</b>
        </span>
      </div>
    </p>
 </div>

<script>
var parentEls = $("b").parents('div');
var names = '';
names = $(parentEls).attr('id');
$("b").append("<strong>" + names+ "</strong>");
console.info($(parentEls));

</script>

</body>
</html>

發如今element.parents(selector)的返回值上調用attr('id')時,jquery默認是在第0個祖先上調用此方法,,即全部祖先中最接近element的那個祖先,以下圖:數組


一開始查看parents(selector)的實現源碼,沒怎麼看懂,今天看了一下attr(xxx)的源碼,app

jQuery.fn.extend({
    attr: function( name, value ) {
        return access( this, jQuery.attr, name, value, arguments.length > 1 );
    },

    removeAttr: function( name ) {
        return this.each(function() {
            jQuery.removeAttr( this, name );
        });
    }
});

而後找到了access.js:this

// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
    var i = 0,
        len = elems.length,
        bulk = key == null;

    // Sets many values
    if ( jQuery.type( key ) === "object" ) {
        chainable = true;
        for ( i in key ) {
            access( elems, fn, i, key[i], true, emptyGet, raw );
        }

    // Sets one value
    } else if ( value !== undefined ) {
        chainable = true;

        if ( !jQuery.isFunction( value ) ) {
            raw = true;
        }

        if ( bulk ) {
            // Bulk operations run against the entire set
            if ( raw ) {
                fn.call( elems, value );
                fn = null;

            // ...except when executing function values
            } else {
                bulk = fn;
                fn = function( elem, key, value ) {
                    return bulk.call( jQuery( elem ), value );
                };
            }
        }

        if ( fn ) {
            for ( ; i < len; i++ ) {
                fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
            }
        }
    }

    return chainable ?
        elems :

        // Gets
        bulk ?
            fn.call( elems ) :
//好像緣由就在這裏:elems[0]
            len ? fn( elems[0], key ) : emptyGet;
};

大概就是在第0個元素上調用的方法,因此我在代碼中那麼寫就歪打正着了,若是元素外層有不止一個匹配selector的祖先,而我要在第二個祖先上調用方法,這麼寫就會出錯了;
spa

相關文章
相關標籤/搜索