撩一下一些必要的js工具函數

asule216 8年前發布 | 13K 次閱讀 JavaScript開發 JavaScript

不管是什么項目,總有一些基本的功能函數默默的躺在你的工具庫中,為你遮擋bug,提升性能,一起來復習下!

debounce

當監聽一些scroll,resize事件時,如果我們什么都不限制,srcoll事件在滾動過程中會一直觸發,極大的影響性能,這個時候,就需要節流函數debounce。debounce函數返回一個函數,在給定的時間間隔下,連續被調用將不會觸發。

/* 事件停止被觸發N秒后才會再次觸發回調 * @param {Function} func - 回調執行函數 * @param {String} wait - 觸發間隔 * @param {Boolean} immediate - 是否延時執行 */
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

// Usage
var myEfficientFn = debounce(function() {
    // todo
}, 250);
window.addEventListener('resize', myEfficientFn);

poll

很多時候,我們需要了解某個函數的執行狀態,并根據狀態執行相應的處理。在沒有事件通知時,需要以一定的時間間隔輪詢執行狀態。

/* 輪詢條件函數,根據狀態執行相應回調 * @param {Function} fn- 條件函數 * @param {Function} callback - 成功回調 * @param {Function} errback - 失敗回調 * @param {int} timeout - 超時間隔 * @param {int} interval - 輪詢間隔 */
function poll(fn, callback, errback, timeout, interval) {
    var endTime = Number(new Date()) + (timeout || 2000);
    interval = interval || 100;

    (function p() {
            // If the condition is met, we're done! 
            if(fn()) {
                callback();
            }
            // If the condition isn't met but the timeout hasn't elapsed, go again
            else if (Number(new Date()) < endTime) {
                setTimeout(p, interval);
            }
            // Didn't match and too much time, reject!
            else {
                errback(new Error('timed out for ' + fn + ': ' + arguments));
            }
    })();
}

// Usage: ensure element is visible
poll(
    function() {
        return document.getElementById('lightbox').offsetWidth > 0;
    },
    function() {
        // Done, success callback
    },
    function() {
        // Error, failure callback
    }
);

once

實用的執行一次函數,不用多解釋。雖然很簡單的函數,但是防止重復加載或者初始化的習慣必須養成。

function once(fn, context) { 
    var result;

    return function() { 
        if(fn) {
            result = fn.apply(context || this, arguments);
            fn = null;
        }

        return result;
    };
}

// Usage
var canOnlyFireOnce = once(function() {
    console.log('Fired!');
});

getAbsoluteUrl

從字符串變量中獲取絕對url路徑并沒有那么容易,URL構造函數必須提供必要的參數,getAbsoluteUrl函數可以單純的從字符串輸入中得到絕對路徑。

var getAbsoluteUrl = (function() {
    var a;

    return function(url) {
        if(!a) a = document.createElement('a');
        a.href = url;

        return a.href;
    };
})();

// Usage
getAbsoluteUrl('/shirlyzhang');  // "http://imweb.io/shirlyzhang"

isNative

當需要重寫某個函數時,必須先確定其是否是原生函數。

(function() {
  var toString = Object.prototype.toString;
  var fnToString = Function.prototype.toString;
  // 構造函數,數組
  var reHostCtor = /^\[object .+?Constructor\]$/;

  var reNative = RegExp('^' +
    // 強制轉換(Object-toString)為字符串
    String(toString)
    // 轉移特殊字符
    .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&')
    // 替換 `toString` 為 `.*?`, 保持模板通用
    // 替換 `for ...` 等字符來支持添加了額外信息的環境
    .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  );

  function isNative(value) {
    var type = typeof value;
    return type == 'function'
      // 使用 `Function#toString` 來繞過value原生的 `toString` 方法,避免誤判
      ? reNative.test(fnToString.call(value))
      // 回退到宿主對象檢查。因為某些環境中,會將類型數組當做DOM方法。
      : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false;
  }

  module.exports = isNative;
}());

// Usage
isNative(alert); // true
isNative(myCustomFunction); // false

insertRule

使用css選擇器來選取節點修改樣式不太高效,可以選擇用js新建一段css樣式規則插入。

var sheet = (function() {
    var style = document.createElement('style');

    // WebKit 兼容
    style.appendChild(document.createTextNode(''));

    document.head.appendChild(style);
    return style.sheet;
})();

// Usage
sheet.insertRule("header { float: left; opacity: 0.8; }", 1);

matchesSelector

判斷頁面內的元素是否具有某些屬性值。

function matchesSelector(el, selector) {
    var p = Element.prototype;
    var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {
        return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
    };
    return f.call(el, selector);
}

// Usage
matchesSelector(document.getElementById('myDiv'), 'div.someSelector[some-attribute=true]')

來自: http://imweb.io/topic/5704a23a06f2400432c1397f

 本文由用戶 asule216 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!