Useful Javascript snippets

Over some time, I’ve collected and/or modified a few Javascript snippets that I find useful. Some are polyfills, some are additions:

STRING.padStart and STRING.padEnd

// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
if (!String.prototype.padStart) {
  String.prototype.padStart = function padStart(targetLength, padString) {
    targetLength = targetLength >> 0; //truncate if number, or convert non-number to 0;
    padString = String(typeof padString !== 'undefined' ? padString : ' ');
    if (this.length >= targetLength) {
      return String(this);
    } else {
      targetLength = targetLength - this.length;
      if (targetLength > padString.length) {
        padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
      }
      return padString.slice(0, targetLength) + String(this);
    }
  };
}

if (!String.prototype.padEnd) {
  String.prototype.padEnd = function padEnd(targetLength, padString) {
    targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
    padString = String(typeof padString !== 'undefined' ? padString : ' ');
    if (this.length > targetLength) {
      return String(this);
    } else {
      targetLength = targetLength - this.length;
      if (targetLength > padString.length) {
        padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
      }
      return String(this) + padString.slice(0, targetLength);
    }
  };
}

ARRAY.filter and ARRAY.reject

// https://gist.github.com/chad3814/2924672
if (!Array.prototype.filter) {
  // augment the Array prototype with a filter() that conforms
  // to ECMAScript5
  // iterator - this function is called for each item, if it return
  // a truthy value, that item is added to the returned array
  // context - this is optional context to call the iterator. 'this'
  // inside the iterator will be set to context.
  // returns an array with only items for which the iterator returned
  // a truthy value
  Array.prototype.filter = function (iterator, context) {
    var arr = [];
    var i;
    for (i = 0; i < this.length; i += 1) {
      if (iterator.call(context, this[i])) {
        arr.push(this[i]);
      }
    }
    return arr;
  };
}

if (!Array.prototype.reject) {
  // augment the Array prototype with a reject() that is the opposite
  // of filter().
  // iterator - this function is called for each item, if it return
  // a truthy value, that item is not added to the returned array
  // context - this is optional context to call the iterator. 'this'
  // inside the iterator will be set to context.
  // returns an array with only items for which the iterator did not
  // return a truthy value
  Array.prototype.reject = function (iterator, context) {
    return this.filter(function (item) {
      return !iterator.call(context, item);
    });
  };
}

jQuery :onScreen selector

// onScreen jQuery plugin v0.2.1
// (c) 2011-2013 Ben Pickles
//
// http://benpickles.github.io/onScreen
//
// Released under MIT license.
(($) => {
  $.expr[":"].onScreen = function(elem) {
    var $window = $(window);
    var viewport_top = $window.scrollTop();
    var viewport_height = $window.height();
    var viewport_bottom = viewport_top + viewport_height;
    var $elem = $(elem);
    var top = $elem.offset().top;
    var height = $elem.height();
    var bottom = top + height;
    return (top >= viewport_top && top < viewport_bottom) ||
           (bottom > viewport_top && bottom <= viewport_bottom) ||
           (height > viewport_height && top <= viewport_top && bottom >= viewport_bottom)
  }
})(jQuery);

jQuery ELEMENT.isAfter and ELEMENT.isBefore

// https://stackoverflow.com/a/20141791
(($) => {
  $.fn.isAfter = function(sel){
    return this.prevAll().filter(sel).length !== 0;
  };
  $.fn.isBefore= function(sel){
    return this.nextAll().filter(sel).length !== 0;
  };
})(jQuery);

ARRAY.clone, ARRAY.deepClone, OBJECT.clone and OBJECT.deepClone

// adapted from https://medium.com/@ziyoshams/deep-copying-javascript-arrays-4d5fc45a6e3e
if (!Array.prototype.clone) {
  // deep copy of Array
  Array.prototype.clone = function () {
    var copy = new Array;
    this.forEach(elem => {
      if (Array.isArray(elem)) {
        copy.push(elem.clone());
      } else if (typeof elem === "object") {
        copy.push(elem.clone());
      } else {
        copy.push(elem);
      }
    });
    return copy;
  };
}

if (!Object.prototype.clone) {
  // deep copy of Object
  Object.prototype.clone = function () {
    var copy = new Object;
    for (var [key, value] of Object.entries(this)) {
      if (Array.isArray(value)) {
        copy[key] = value.clone();
      } else if (typeof value === "object") {
        copy[key] = value.clone();
      } else {
        copy[key] = value;
      }
    };
    return copy;
  };
}

// deepClone uses any deepClone method that's available
if (!Array.prototype.deepClone) {
  Array.prototype.deepClone = function () {
    var copy = new Array;
    this.forEach(elem => {
      if (elem && elem.deepClone && typeof elem.deepClone === "function") {
        copy.push(elem.deepClone());
      } else {
        copy.push(elem);
      }
    });
    return copy;
  };
}

if (!Object.prototype.deepClone) {
  Object.prototype.deepClone = function () {
    var copy = new Object;
    for (var [key, value] of Object.entries(this)) {
      if (value && value.deepClone && typeof value.deepClone === "function") {
        copy[key] = value.deepClone();
      } else {
        copy[key] = value;
      }
    };
    return copy;
  };
}

encodeURIComponent, but for the ISO-8859-1 charset

// A replacement for encodeURIComponent, that allows Latin1/ISO-8859-1 encodings to pass through
function encodeURIComponentLatin1(str) {
  return str.replace(/([^a-zA-Z0-9_\.,-])/g, (match, p1) => {return "%" + p1.charCodeAt(0).toString(16).padStart(2, "0");});
}

Escape strings for use in regular expressions

// A function to escape a string for regular expression use, similar to Perl's \Q ... \E, so it can be used in a future regular expression
function escapeRegExp(str) {
  return str.replace(/([\\\+\(\)\{\}\^\$\?\.\|])/g, (match, p1) => {return "\\" + p1;});
}

And finally, how to restore console.log if some framework you are using (don’t ask!) has removed it

// https://stackoverflow.com/questions/7089443/restoring-console-log
(() => {
  var i = document.createElement('iframe');
  i.style.display = 'none';
  document.body.appendChild(i);
  window.console = i.contentWindow.console;
})();

 

 

 

 

 

 

This entry was posted in Development and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.