>  기사  >  웹 프론트엔드  >  jquery에서 언제 attr()을 사용하고 언제 prop()을 사용합니까?

jquery에서 언제 attr()을 사용하고 언제 prop()을 사용합니까?

伊谢尔伦
伊谢尔伦원래의
2017-06-17 13:43:211479검색

누군가가 여러 개를 주었습니다 Select 플러그인이 질문을 했습니다:

setSelects jquery 1.9.0을 사용할 때 Firefox에서 작동하지 않습니다. 저는 jQuery 1.8.3 버전을 사용하고 있으며 jQuery 1.9.0 버전을 사용해 본 적이 없습니다.

그러므로 코드를 디버깅 시작하세요. 1.9.0 버전에서는

<input type="checkbox" />
<script>
    $(function() {
        $('input').click(function() {
            $(this).attr('checked');
        });
    });
</script>

확인란을 클릭하세요. 결과는 모두 정의되지 않습니다.

그리고 1.8.3 버전에서는 결과가 확인되고 정의되지 않습니다.

이쯤 되면 attr() 메소드 사용의 문제인 질문에 대한 답을 찾았고, 공식 문서를 확인해보니 jQuery 1.6부터 새로운 메소드 prop()이 있다는 걸 알게 됐어요. , 그러나 한 번도 사용된 적이 없습니다. 중국어로는 각각 속성과 속성을 가져오거나 설정하는 메소드인데 왜 prop() 메소드를 추가해야 할까요?

Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior.

jQuery 1.6 이전에는 attr()을 사용하면 때때로 일관되지 않은

동작

이 발생했습니다. 그럼 언제 attr()을 사용하고 언제 prop()을 사용할까요?

To retrieve and change DOM properties such as the checked, selected, or disabled state of form elements, use the .prop() method.

공식 권장 사항에 따르면:

checked, selected 또는 비활성화와 같은 두 개의

속성 true와 false가 있는 속성은 prop()을 사용하고 다른 속성은 attr()을 사용합니다이 시점에서 attr('checked')를 변경합니다. 언급된 문제를 해결하려면 prop('checked')를 사용하세요.

잠깐만, 아직 문제가 해결되지 않은 것 같습니다. 처음에 예제에서 attr()을 사용했을 때 jQuery 1.8.3과 1.9.0 사이에 차이가 있는 이유는 무엇인가요?

그들 사이의 차이점을 알고 싶다면, 가장 좋은 방법은 소스 코드를 보는 것입니다:

1.8.3 attr():

attr: function( elem, name, value, pass ) {    var ret, hooks, notxml,
        nType = elem.nodeType;    // don't get/set attributes on text, comment and attribute nodes
    if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {        return;
    }    if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {        return jQuery( elem )[ name ]( value );
    }    // Fallback to prop when attributes are not supported
    if ( typeof elem.getAttribute === "undefined" ) {        return jQuery.prop( elem, name, value );
    }

    notxml = nType !== 1 || !jQuery.isXMLDoc( elem );    // All attributes are lowercase
    // Grab necessary hook if one is defined
    if ( notxml ) {
        name = name.toLowerCase();
        hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
    }    if ( value !== undefined ) {        if ( value === null ) {
            jQuery.removeAttr( elem, name );            return;

        } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {            return ret;

        } else {
            elem.setAttribute( name, value + "" );            return value;
        }

    } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {        return ret;

    } else {

        ret = elem.getAttribute( name );        // Non-existent attributes return null, we normalize to undefined
        return ret === null ?
            undefined :
            ret;
    }
}

1.9.0 attr():

 attr: function( elem, name, value, pass ) {   
  var ret, hooks, notxml,
        nType = elem.nodeType;    
  // don't get/set attributes on text, comment and attribute nodes
    if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {        
           return;
    }    
   if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {        
        return jQuery( elem )[ name ]( value );
    }    
        // Fallback to prop when attributes are not supported
    if ( typeof elem.getAttribute === "undefined" ) {       
         return jQuery.prop( elem, name, value );
    }

    notxml = nType !== 1 || !jQuery.isXMLDoc( elem );    
   // All attributes are lowercase
    // Grab necessary hook if one is defined
    if ( notxml ) {
        name = name.toLowerCase();
        hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
    }    
   if ( value !== undefined ) {        
       if ( value === null ) {
            jQuery.removeAttr( elem, name );            
            return;

        } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {            
            return ret;

        } else {
            elem.setAttribute( name, value + "" );           
             return value;
        }

    } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {      
               return ret;

    } else {

        ret = elem.getAttribute( name );        
      // Non-existent attributes return null, we normalize to undefined
        return ret === null ?
            undefined :
            ret;
    }
}

prop of 1.8.3 1.9.0 ()은 동일합니다:

prop: function( elem, name, value ) {    
  var ret, hooks, notxml,
   nType = elem.nodeType;    
   // don't get/set properties on text, comment and attribute nodes
    if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {        
    return;
    }

    notxml = nType !== 1 || !jQuery.isXMLDoc( elem );    
    if ( notxml ) {        
    // Fix name and attach hooks
        name = jQuery.propFix[ name ] || name;
        hooks = jQuery.propHooks[ name ];
    }   
     if ( value !== undefined ) {        
         if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {           
          return ret;

        } else {            
        return ( elem[ name ] = value );
        }

    } else {        
       if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {            
       return ret;

        } else {            
        return elem[ name ];
        }
    }
}

首先,我们看下 attr() 和 prop() 的区别

attr() 里面,最关键的两行代码

elem.setAttribute( name, value + "" ); 
ret =  elem.getAttribute( name );

很明显的看出来,使用的 DOM 的 API setAttribute() 和 getAttribute() 方法操作的属性元素节点。

prop() 里面,最关键的两行代码

return ( elem[ name ] = value );return elem[ name ];

可以理解为 document.getElementById(el)[name] = value,这是转化成 element 的一个属性。

对比调试 1.9.0 和 1.8.3 的 attr() 方法,发现两者的区别在于

hooks.get( elem, name ))

返回的值不一样,具体的实现:

1.8.3 中

boolHook = {
    get: function( elem, name ) {        
    // Align boolean attributes with corresponding properties
        // Fall back to attribute presence where some booleans are not supported
        var attrNode,
            property = jQuery.prop( elem, name );        
            return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
            name.toLowerCase() :           
             undefined;
    }
}

1.9.0 中

boolHook = {    get: function( elem, name ) {       
 var
            // Use .prop to determine if this attribute is understood as boolean
            prop = jQuery.prop( elem, name ),          
              // Fetch it accordingly
            attr = typeof prop === "boolean" && elem.getAttribute( name ),
            detail = typeof prop === "boolean" ?

                getSetInput && getSetAttribute ?
                    attr != null :                   
                     // oldIE fabricates an empty string for missing boolean attributes
                    // and conflates checked/selected into attroperties
                    ruseDefault.test( name ) ?
                        elem[ jQuery.camelCase( "default-" + name ) ] :
                        !!attr :               
                         // fetch an attribute node for properties not recognized as boolean
                elem.getAttributeNode( name );       
                 return detail && detail.value !== false ?
            name.toLowerCase() :
            undefined;
    }
}

由此可见,1.9.0 开始不建议使用 attr() 来对具有 true 和 false 两个属性的属性进行操作了。

那么我们的结论是:

具有 true 和 false 两个属性的属性,如 checked, selected 或者 disabled 使用prop(),其他的使用 attr(),具体见下表:

위 내용은 jquery에서 언제 attr()을 사용하고 언제 prop()을 사용합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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