attrchange_ext.js 4.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. An extension for attrchange jQuery plugin
  3. http://meetselva.github.io/attrchange/
  4. About License:
  5. Copyright (C) 2013-2014 Selvakumar Arumugam
  6. You may use attrchange ext plugin under the terms of the MIT Licese.
  7. https://github.com/meetselva/attrchange/blob/master/MIT-License.txt
  8. */
  9. $.fn.attrchange.extensions = { /*attrchange option/extension*/
  10. disconnect: function (o) {
  11. if (typeof o !== 'undefined' && o.isPhysicalDisconnect) {
  12. return this.each(function() {
  13. var attrchangeMethod = $(this).data('attrchange-method');
  14. if (attrchangeMethod == 'propertychange' || attrchangeMethod == 'DOMAttrModified') {
  15. $(this).off(attrchangeMethod);
  16. } else if (attrchangeMethod == 'Mutation Observer') {
  17. $(this).data('attrchange-obs').disconnect();
  18. } else if (attrchangeMethod == 'polling') {
  19. clearInterval($(this).data('attrchange-polling-timer'));
  20. }
  21. }).removeData('attrchange-method');
  22. } else { //logical disconnect
  23. return this.data('attrchange-tdisconnect', 'tdisconnect'); //set a flag that prevents triggering callback onattrchange
  24. }
  25. },
  26. remove: function (o) {
  27. return $.fn.attrchange.extensions['disconnect'].call(this, {isPhysicalDisconnect: true});
  28. },
  29. getProperties: function (o) {
  30. var attrchangeMethod = $(this).data('attrchange-method');
  31. var pollInterval = $(this).data('attrchange-pollInterval');
  32. return {
  33. method: attrchangeMethod,
  34. isPolling: (attrchangeMethod == 'polling'),
  35. pollingInterval: (typeof pollInterval === 'undefined')?0:parseInt(pollInterval, 10),
  36. status: (typeof attrchangeMethod === 'undefined')?'removed': (typeof $(this).data('attrchange-tdisconnect') === 'undefined')?'connected':'disconnected'
  37. }
  38. },
  39. reconnect: function (o) {//reconnect possible only when there is a logical disconnect
  40. return this.removeData('attrchange-tdisconnect');
  41. },
  42. polling: function (o) {
  43. if (o.hasOwnProperty('isComputedStyle') && o.isComputedStyle == 'true') { /* extensive and slow - polling to check on computed style properties */
  44. return this.each(function(i, _this) {
  45. if (!o.hasOwnProperty('properties') ||
  46. Object.prototype.toString.call(o.properties) !== '[object Array]' ||
  47. o.properties.length == 0) { return false; } //return if no properties found
  48. var attributes = {}; //store computed properties
  49. for (var i = 0; i < o.properties.length; i++) {
  50. attributes[o.properties[i]] = $(this).css(o.properties[i]);
  51. }
  52. var _this = this;
  53. $(this).data('attrchange-polling-timer', setInterval(function () {
  54. var changes = {}, hasChanges = false; // attrName: { oldValue: xxx, newValue: yyy}
  55. for (var comuptedVal, i = 0; i < o.properties.length; i++){
  56. comuptedVal = $(_this).css(o.properties[i]);
  57. if (attributes[o.properties[i]] !== comuptedVal) {
  58. hasChanges = true;
  59. changes[o.properties[i]] = {oldValue: attributes[o.properties[i]], newValue: comuptedVal};
  60. attributes[o.properties[i]] = comuptedVal //add the attribute to the orig
  61. }
  62. }
  63. if (hasChanges && typeof $(_this).data('attrchange-tdisconnect') === 'undefined') { //disconnected logically
  64. o.callback.call(_this, changes);
  65. }
  66. }, (o.pollInterval)?o.pollInterval: 1000)).data('attrchange-method', 'polling').data('attrchange-pollInterval', o.pollInterval);
  67. });
  68. } else {
  69. return this.each(function(i, _this) { /* this one is programmatic polling */
  70. var attributes = {};
  71. for (var attr, i=0, attrs=_this.attributes, l=attrs.length; i<l; i++){
  72. attr = attrs.item(i);
  73. attributes[attr.nodeName] = attr.nodeValue;
  74. }
  75. $(_this).data('attrchange-polling-timer', setInterval(function () {
  76. var changes = {}, hasChanges = false; // attrName: { oldValue: xxx, newValue: yyy}
  77. for (var attr, i=0, attrs=_this.attributes, l=attrs.length; i<l; i++){
  78. attr = attrs.item(i);
  79. if (attributes.hasOwnProperty(attr.nodeName) &&
  80. attributes[attr.nodeName] != attr.nodeValue) { //check the values
  81. changes[attr.nodeName] = {oldValue: attributes[attr.nodeName], newValue: attr.nodeValue};
  82. hasChanges = true;
  83. } else if (!attributes.hasOwnProperty(attr.nodeName)) { //new attribute
  84. changes[attr.nodeName] = {oldValue: '', newValue: attr.nodeValue};
  85. hasChanges = true;
  86. }
  87. attributes[attr.nodeName] = attr.nodeValue; //add the attribute to the orig
  88. }
  89. if (hasChanges && typeof $(_this).data('attrchange-tdisconnect') === 'undefined') { //disconnected logically
  90. o.callback.call(_this, changes);
  91. }
  92. }, (o.pollInterval)?o.pollInterval: 1000)).data('attrchange-method', 'polling').data('attrchange-pollInterval', o.pollInterval);
  93. });
  94. }
  95. }
  96. }