以前的驗(yàn)證碼很簡(jiǎn)單,就是一個(gè)帶些背景色或背景圖和干擾線的純數(shù)字字母類的驗(yàn)證碼,現(xiàn)在已經(jīng)發(fā)展變得很豐富了。我見(jiàn)過(guò)的就有好幾種:純字母數(shù)字類,數(shù)學(xué)計(jì)算類,依次點(diǎn)擊圖片上的文字類,從下列圖片列表里選取符合描述的圖片類,拼圖驗(yàn)證碼類。鑒于,本人要使用拼圖驗(yàn)證碼類,故介紹一下自己的調(diào)查使用情況。
我們先看看2種類型的滑動(dòng)拼圖驗(yàn)證碼:


- 第一種:拼圖是簡(jiǎn)單的矩形。 這種方式可以用css(background-size和background-position)實(shí)現(xiàn)摳圖的ui部分。你可以此插件,還不錯(cuò)。兼容ie9及以上。
- 第二種:拼圖是不規(guī)則圖形。 這種方式,就沒(méi)法直接用css實(shí)現(xiàn)摳圖部分了,得用canvas來(lái)做??梢詤⒖?a target="_blank" rel="nofollow">此插件。
我是需要第二種,大致記錄以下本人使用過(guò)程碰到的問(wèn)題和最后的解決方式。
此插件的github源碼地址:https://github.com/yeild/jigsaw,demo頁(yè)面地址:https://yeild.github.io/jigsaw/src/demo.html。
兼容性
此插件不兼容IE瀏覽器。查看項(xiàng)目源碼,發(fā)現(xiàn)js使用了不少es6的新語(yǔ)法。
然后用Babel轉(zhuǎn)了一下,發(fā)現(xiàn)還是有不兼容IE的方法。
比如Object.assign方法。為了兼容,補(bǔ)上以下代碼:
// 不支持assign方法的兼容寫(xiě)法
if (typeof Object.assign != 'function') {
// Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
又比如:element.classList的相關(guān)的方法add,remove。
想兼容,請(qǐng)補(bǔ)上:
//不支持element.classList方法的兼容寫(xiě)法(ie10及以下)
if (!("classList" in document.documentElement)) {
Object.defineProperty(HTMLElement.prototype, 'classList', {
get: function() {
var self = this;
function update(fn) {
return function(value) {
var classes = self.className.split(/\s+/g),
index = classes.indexOf(value);
fn(classes, index, value);
self.className = classes.join(" ");
}
}
return {
add: update(function(classes, index, value) {
if (!~index) classes.push(value);
}),
remove: update(function(classes, index) {
if (~index) classes.splice(index, 1);
}),
toggle: update(function(classes, index, value) {
if (~index)
classes.splice(index, 1);
else
classes.push(value);
}),
contains: function(value) {
return !!~self.className.split(/\s+/g).indexOf(value);
},
item: function(i) {
return self.className.split(/\s+/g)[i] || null;
}
};
}
});
}
還有,當(dāng)使用canvas相關(guān)相關(guān)getImageData和putImageData做摳圖的代碼出來(lái)時(shí),在IE9和IE10有個(gè)圖片文件跨域問(wèn)題(報(bào)錯(cuò):SecurityError)。
第一種解決方式:圖片文件跟項(xiàng)目方一起就不存在跨域問(wèn)題了。第二種就是不適用getImageData和putImageData方法。用其他實(shí)現(xiàn)方式代替,見(jiàn)下面帶代碼:
//getImageData方法和putImageData方法在IE9和IE10上,涉及到文件路徑的跨域訪問(wèn)問(wèn)題。
// console.log('(x:'+_this.x+',y:'+_this.y+')');
if(navigator.userAgent.indexOf("MSIE") > -1){
_this.block.style.marginLeft = '-'+(_this.x-3)+'px';//不抵邊,空3px
}else{
var ImageData = _this.blockCtx.getImageData(_this.x - 3, y, L, L);
_this.block.width = L;
_this.blockCtx.putImageData(ImageData, 0, y);
}
還有,在IE中,在canvas上繪圖有順序步驟的。如果在IE中出現(xiàn)下圖摳圖區(qū)未繪制成功,請(qǐng)調(diào)整代碼順序。

解決方式:

最終調(diào)整完后的demo,見(jiàn)js實(shí)現(xiàn)滑動(dòng)拼圖驗(yàn)證碼