attr.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. define( [
  2. "../core",
  3. "../core/access",
  4. "../core/nodeName",
  5. "./support",
  6. "../var/rnothtmlwhite",
  7. "../selector"
  8. ], function( jQuery, access, nodeName, support, rnothtmlwhite ) {
  9. "use strict";
  10. var boolHook,
  11. attrHandle = jQuery.expr.attrHandle;
  12. jQuery.fn.extend( {
  13. attr: function( name, value ) {
  14. return access( this, jQuery.attr, name, value, arguments.length > 1 );
  15. },
  16. removeAttr: function( name ) {
  17. return this.each( function() {
  18. jQuery.removeAttr( this, name );
  19. } );
  20. }
  21. } );
  22. jQuery.extend( {
  23. attr: function( elem, name, value ) {
  24. var ret, hooks,
  25. nType = elem.nodeType;
  26. // Don't get/set attributes on text, comment and attribute nodes
  27. if ( nType === 3 || nType === 8 || nType === 2 ) {
  28. return;
  29. }
  30. // Fallback to prop when attributes are not supported
  31. if ( typeof elem.getAttribute === "undefined" ) {
  32. return jQuery.prop( elem, name, value );
  33. }
  34. // Attribute hooks are determined by the lowercase version
  35. // Grab necessary hook if one is defined
  36. if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  37. hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
  38. ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
  39. }
  40. if ( value !== undefined ) {
  41. if ( value === null ) {
  42. jQuery.removeAttr( elem, name );
  43. return;
  44. }
  45. if ( hooks && "set" in hooks &&
  46. ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
  47. return ret;
  48. }
  49. elem.setAttribute( name, value + "" );
  50. return value;
  51. }
  52. if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
  53. return ret;
  54. }
  55. ret = jQuery.find.attr( elem, name );
  56. // Non-existent attributes return null, we normalize to undefined
  57. return ret == null ? undefined : ret;
  58. },
  59. attrHooks: {
  60. type: {
  61. set: function( elem, value ) {
  62. if ( !support.radioValue && value === "radio" &&
  63. nodeName( elem, "input" ) ) {
  64. var val = elem.value;
  65. elem.setAttribute( "type", value );
  66. if ( val ) {
  67. elem.value = val;
  68. }
  69. return value;
  70. }
  71. }
  72. }
  73. },
  74. removeAttr: function( elem, value ) {
  75. var name,
  76. i = 0,
  77. // Attribute names can contain non-HTML whitespace characters
  78. // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
  79. attrNames = value && value.match( rnothtmlwhite );
  80. if ( attrNames && elem.nodeType === 1 ) {
  81. while ( ( name = attrNames[ i++ ] ) ) {
  82. elem.removeAttribute( name );
  83. }
  84. }
  85. }
  86. } );
  87. // Hooks for boolean attributes
  88. boolHook = {
  89. set: function( elem, value, name ) {
  90. if ( value === false ) {
  91. // Remove boolean attributes when set to false
  92. jQuery.removeAttr( elem, name );
  93. } else {
  94. elem.setAttribute( name, name );
  95. }
  96. return name;
  97. }
  98. };
  99. jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
  100. var getter = attrHandle[ name ] || jQuery.find.attr;
  101. attrHandle[ name ] = function( elem, name, isXML ) {
  102. var ret, handle,
  103. lowercaseName = name.toLowerCase();
  104. if ( !isXML ) {
  105. // Avoid an infinite loop by temporarily removing this function from the getter
  106. handle = attrHandle[ lowercaseName ];
  107. attrHandle[ lowercaseName ] = ret;
  108. ret = getter( elem, name, isXML ) != null ?
  109. lowercaseName :
  110. null;
  111. attrHandle[ lowercaseName ] = handle;
  112. }
  113. return ret;
  114. };
  115. } );
  116. } );