Reputation: 515
I want to write a small script to invert black and white colors on a certain area of a page. I used an inverting script that I found on another thread and adjusted it to only invert black and white and only on a certain area of the page: http://jsfiddle.net/yQe9t/87/
This works fine on jQuery 1.12.1 and above but Ive noticed that some of the pages that Im working with they still use jQuery 1.9 and for some reason the script does not work properly on there; http://jsfiddle.net/yQe9t/88/ (jquery 1.9 here). I'm unable to change the jQuery version used on those pages so I need to make it compatible with that.
Can someone please help me figure out how to make my code work on older versions as well? I'd like it to work on new and old but dont know enough about Javascript myself to fix it.
My complete Javascript:
$(".invertAll").click (function () {
var Body = $(".unit.size-col-d.width610");
invertElementColors ( $(Body) );
} );
function rgb2hex(rgb){
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
return (rgb && rgb.length === 4) ? "#" +
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
}
function invertElementColors (jNode)
{
jNode.children().each(function () {
invertElementColors ( $(this) );
});
jNode.css ( {
'color' : function (J, oldColor) {
return invertRGB_ColorStr (oldColor);
},
'background-color' : function (J, oldColor) {
return invertRGB_ColorStr (oldColor);
}
} );
}
function invertRGB_ColorStr (oldColorStr)
{
// convert color rgb to hex code so we can easily detect colors
var help = oldColorStr;
var colorHex = rgb2hex(help);
// only convert black and white
if ((colorHex == '#000000') || (colorHex == '#ffffff')) {
//--- Special case
if (oldColorStr == 'transparent') oldColorStr = 'rgb(255, 255, 255)';
//--- Color is text in RGB format. EG: rgb(1, 22, 255)
var colorArray = oldColorStr.match (/\((\d+),\s?(\d+),\s?(\d+)\)/);
var newColorStr = $.map (colorArray, function (byte, J)
{
if (!J) return null;
//--- Invert a decimal byte.
return Math.abs (255 - parseInt (byte) );
}
).join (',');
return 'rgb(' + newColorStr + ')';
} else {
return oldColorStr;
}
}
Upvotes: 1
Views: 106
Reputation: 177965
Fixed it:
var colorArray = oldColorStr.match(/\((\d+),\s?(\d+),\s?(\d+)\)/);
colorArray = colorArray || [];
You do not always get a matching array back from the code you send in these functions and $.map fails when you pass null or anything else without a length in version 1.9 and lower
jNode.css({
'color': function(J, oldColor) {
console.log("J",J,oldColor)
return invertRGB_ColorStr(oldColor);
},
'background-color': function(J, oldColor) {
console.log("J1",J,oldColor)
return invertRGB_ColorStr(oldColor);
}
v1.9;
VM244:102
[h3, context: h3]
VM244:105 J 0 rgb(0, 0, 0)
VM244:128 ocs rgb(0, 0, 0)
VM244:109 J1 0 rgba(0, 0, 0, 0)
VM244:128 ocs rgba(0, 0, 0, 0)
VM244:102
[img.invertAll, context: img.invertAll]
VM244:105 J 0 rgb(0, 0, 0)
VM244:128 ocs rgb(0, 0, 0)
VM244:109 J1 0 rgba(0, 0, 0, 0)
VM244:128 ocs rgba(0, 0, 0, 0)
VM244:102
[div#D1.Payload, context: div#D1.Payload]
VM244:105 J 0 rgb(0, 0, 0)
VM244:128 ocs rgb(0, 0, 0)
v2+
VM244:102
[h3, context: h3]
VM244:105 J 0 rgb(0, 0, 0)
VM244:128 ocs rgb(0, 0, 0)
VM244:109 J1 0 rgba(0, 0, 0, 0)
VM244:128 ocs rgba(0, 0, 0, 0)
VM244:102
[img.invertAll, context: img.invertAll]
VM244:105 J 0 rgb(0, 0, 0)
VM244:128 ocs rgb(0, 0, 0)
VM244:109 J1 0 rgba(0, 0, 0, 0)
VM244:128 ocs rgba(0, 0, 0, 0)
VM244:102
[div#D1.Payload, context: div#D1.Payload]
VM244:105 J 0 rgb(0, 0, 0)
VM244:128 ocs rgb(0, 0, 0)
VM244:109 J1 0 rgb(255, 255, 255)
?
Upvotes: 1
Reputation: 4766
The source for map
in the two jQuery version is different.
One is checking if the value your mapping over is array like before trying to access the property .length
.
map: function( elems, callback, arg ) {
var length, value,
i = 0,
ret = [];
// Go through the array, translating each of the items to their new values
if ( isArrayLike( elems ) ) {
length = elems.length;
The failing does not:
map: function( elems, callback, arg ) {
var value,
i = 0,
length = elems.length,
isArray = isArraylike( elems ),
ret = [];
So when your regex fails, you pass map null
accessing property .length
of null throws an exception.
So solution if you cannot upgrade jQuery your self, only pass a value into map if oldColorStr.match (/\((\d+),\s?(\d+),\s?(\d+)\)/);
doesn't return null
. That will stop the exception.
Upvotes: 2