jQuery version compatibility detection

前端 未结 6 691
刺人心
刺人心 2020-12-09 13:38

Are there any resources that can test a jQuery script/extension/plugin/whatever for version compatibility issues?

相关标签:
6条回答
  • 2020-12-09 13:50

    Here's my quick and dirty solution:

    var versionGTE = function (valueA, valueB) {
      var values = [valueA, valueB];
      values.sort();
      // if valueA > valueB, values will have switched
      return (values[1] === valueA);
    };
    

    Example usage:

    if (versionGTE(jQuery.fn.jquery, "1.3")) {
      // don't use @ in attr selectors
    }
    

    It does an alphabetical sort on the array. The only time it fails is if for some reason the version "x.y" vs "x.y.0". In that case the .0 version is perceived as being greater. It doesn't support "pre" versions either.

    Here's a smaller version:

    var versionGTE = function (valueA, valueB) {
      return ([valueA, valueB].sort()[1] === valueA);
    };
    

    Here's a more reliable function if you're worried about "rc1", "pre", or x.0 versions:

    var versionCompare = function (versionStringA, versionStringB) {
      // quick test of equality before digging in
      if (versionStringA === versionStringB) return 0;
    
      var versionedAlpha = /[a-z]+(\d+)/gi,
          getArray = function (verString) {
            // replace rc1, rc2, beta3, etc with .-1.1, .-1.2, .-1.3, etc
            return verString.replace(versionedAlpha, ".-1.$1").split(".");
          },
          valuesA = getArray(versionStringA),
          valuesB = getArray(versionStringB),
          maxLength = Math.max(valuesA.length, valuesB.length),
          hasLetters = /[a-z]/gi,
          // assume any version with letters is -1 (pre, rc, etc)
          // also assume that any null entries are 0 (1.5 === 1.5.0)
          parseVersion = function (verString) {
            return (verString) ? (hasLetters.test(verString)) ? -1 : parseInt(verString, 10) : 0;
          };
    
      // verify both arrays are the same size
      valuesA.length = maxLength;
      valuesB.length = maxLength;
    
      for (var i = 0; i < maxLength; i++) {
        var valueA = parseVersion(valuesA[i]),
            valueB = parseVersion(valuesB[i]);
    
        if (valueA < valueB) {
          return -1;
        } else if (valueA > valueB) {
          return 1;
        }
      }
    
      // all equal at this point
      return 0;
    };
    

    This is like a sort or .compare function in that it will return 0 if equal, 1 if a > b, and -1 if a < b. Example:

    if (versionCompare(jQuery.fn.jquery, "1.3") >= 0) {
      // don't use @ in attr selectors
    }
    
    0 讨论(0)
  • 2020-12-09 13:55

    Holy smokes people, those are the most verbose solutions ever! Am I missing something? I must be. Below is my solution, what am I missing?

    Compressed version:

    (parseInt(jQuery.fn.jquery.split('.').join('')) > 140) ? alert("Running jquery greater than 1.4.0") : alert("current jquery version is 1.4.0 or less");
    

    Long version for clarity:

    // get version as a string and get rid of the periods. 
    version = jQuery.fn.jquery.split('.').join('');
    
    // Make into one long number for easy comparison.  Example, 171, or 141.
    version = parseInt(version);
    if(version > 141){
        alert("We're using a version greater than 1.4.1");
    }else{
        alert("jQuery version is 1.4.1 or lower");
    }
    
    0 讨论(0)
  • 2020-12-09 13:58

    The code has some bugs, notably

    1. $.isVersion('1.9.2.17', '<', '2.0') returns false
    2. $.isVersion('1.17.2.1', '>', '1.8') returns false

    Solution
    1. is fixed by the attached code.
    2. is not as it's trickier without a complete re-write, and is a rarer case anyway.

    (function($) {
    /**
     * Used for version test cases.
     *
     * @param {string} left A string containing the version that will become
     *        the left hand operand.
     * @param {string} oper The comparison operator to test against. By
     *        default, the "==" operator will be used.
     * @param {string} right A string containing the version that will
     *        become the right hand operand. By default, the current jQuery
     *        version will be used.
     *
     * @return {boolean} Returns the evaluation of the expression, either
     *         true or false.
     */
    $.isVersion = function(left, oper, right) {
        if (left) {
            var pre = /pre/i,
                replace = /[^\d]+/g,
                oper = oper || "==",
                right = right || $().jquery,
                l = left.replace(replace, ''),
                r = right.replace(replace, ''),
                l_len = l.length, r_len = r.length,
                l_pre = pre.test(left), r_pre = pre.test(right);
    
            l = (r_len > l_len ? parseInt(l) * Math.pow(10, (r_len - l_len)) : parseInt(l));
            r = (l_len > r_len ? parseInt(r) * Math.pow(10, (l_len - r_len)) : parseInt(r));
    
            switch(oper) {
                case "==": {
                    return (true === (l == r && (l_pre == r_pre)));
                }
                case ">=": {
                    return (true === (l >= r && (!l_pre || l_pre == r_pre)));
                }
                case "<=": {
                    return (true === (l <= r && (!r_pre || r_pre == l_pre)));
                }
                case ">": {
                    return (true === (l > r || (l == r && r_pre)));
                }
                case "<": {
                    return (true === (l < r || (l == r && l_pre)));
                }
            }
        }
    
        return false;
    }
    })(jQuery);
    
    0 讨论(0)
  • 2020-12-09 14:01

    There are no automated tools for this, at least that I have ever seen. The reasoning for this is the jQuery core team tries to not introduce breaking changes unless there's a real long-term benefit. This means that when there are breaking changes, what you wanted isn't something an automated system can always tell you.

    Let's use jQuery 1.4 as an example, here's a list of breaking changes:
    http://jquery14.com/day-01/jquery-14#backwards

    • jQuery() is now an empty set, good or bad?
    • jQuery.browser.version is now browser version, good or bad?
    • JSON is now subject to much stricter parsing, good or bad?

    Those are just a handful, but whether they break or help your code often depends. Now if you had .attr(val, func()) then obviously this is 1.4+ only, that you could detect...so an engine that could determine the minimum version of jQuery your code could use may be possible.

    Checking compatibility issues, which I take to mean breaking changes in most cases, would be much more difficult, because they are (mostly) by nature very odd or corner cases that are broken...otherwise the team wouldn't have broken them :)

    0 讨论(0)
  • 2020-12-09 14:09

    Are you wanting to get the current version of jQuery and test it to see if its a certain version?

    $().jquery;
    

    That will get the version.

    Metropolis

    0 讨论(0)
  • 2020-12-09 14:10

    Just wrote a small jQuery plugin to help with version compatibility issues... feel free to improve upon it.

    (function($) {
        /**
         * Used for version test cases.
         * 
         * @param {string} left A string containing the version that will become
         *        the left hand operand.
         * @param {string} oper The comparison operator to test against. By
         *        default, the "==" operator will be used.
         * @param {string} right A string containing the version that will
         *        become the right hand operand. By default, the current jQuery
         *        version will be used.
         *        
         * @return {boolean} Returns the evaluation of the expression, either
         *         true or false.
         */
        $.isVersion = function(left, oper, right) {
            if (left) {
                var pre = /pre/i,
                    replace = /[^\d]+/g,
                    oper = oper || "==",
                    right = right || $().jquery,
                    l = left.replace(replace, ''),
                    r = right.replace(replace, ''),
                    l_len = l.length, r_len = r.length,
                    l_pre = pre.test(left), r_pre = pre.test(right);
    
                l = (r_len > l_len ? parseInt(l) * ((r_len - l_len) * 10) : parseInt(l));
                r = (l_len > r_len ? parseInt(r) * ((l_len - r_len) * 10) : parseInt(r));
    
                switch(oper) {
                    case "==": {
                        return (true === (l == r && (l_pre == r_pre)));
                    }
                    case ">=": {
                        return (true === (l >= r && (!l_pre || l_pre == r_pre)));
                    }
                    case "<=": {
                        return (true === (l <= r && (!r_pre || r_pre == l_pre)));
                    }
                    case ">": {
                        return (true === (l > r || (l == r && r_pre)));
                    }
                    case "<": {
                        return (true === (l < r || (l == r && l_pre)));
                    }
                }
            }
    
            return false;
        }
    })(jQuery);
    

    Can be used like so:

    $.isVersion("1.4.2"); // returns true, if $().jquery == "1.4.2"
    $.isVersion("1.3.2", ">"); // returns true if $().jquery > "1.3.2"
    $.isVersion("1.3", ">", "1.2.6"); // returns true
    $.isVersion("1.3.2", "<", "1.3.1"); // returns false
    $.isVersion("1.4.0", ">=", "1.3.2"); // returns true
    $.isVersion("1.4.1", "<=", "1.4.1"); // returns true
    

    Also supports pre-releases (releases are weighed heavier than pre-releases, so that 1.4.0pre < 1.4.0):

    $.isVersion("1.4.2", "<=", "1.4.2pre"); // returns false
    
    0 讨论(0)
提交回复
热议问题