Underscore的_.isEqual分不清2张图片
Underscore's _.isEqual can't distinguish 2 images
我的应用程序使用 Backbone.js
,并且在捕获图像上的更改事件时遇到一些问题,因为它使用 Underscore.js
的 _.isEqual
来决定是否更改属性,但是,它不适用于 img
:
// Backbone inits.
var Model = Backbone.Model.extend({
defaults: {
image : null
},
initialize: function() {
this.listenTo(this, 'change', this.handleChange);
},
handleChange: function(model) {
var changes = this.changedAttributes();
if (changes) {
for (var k in changes) {
console.log(k + 'in the model changed.', this.get(k));
}
}
}
});
var testModel = new Model();
console.log(testModel.get('image'));
// Test change work
testModel.set('testval', 1);
testModel.set('testval', 2);
var canvas = document.querySelector('#testCanvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, 50, 50);
var canvas2 = document.querySelector('#testCanvas2');
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = 'red';
ctx2.fillRect(0, 0, 300, 50);
var image1 = new Image();
var image2 = new Image();
image1.onload = function() {
document.querySelector('#test').appendChild(image1);
// backbone
testModel.set('image', image1);
image2.onload = function() {
document.querySelector('#test').appendChild(image2);
testModel.set('image', image2); // This not fire
console.log("Use isEqual : ",_.isEqual(image1, image2));
console.log("Use == : ", image1 == image2);
console.log("Use === : ", image1 === image2);
};
image2.src = canvas2.toDataURL();
};
image1.src = canvas.toDataURL();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
<div id="test">
<canvas id="testCanvas" width="300" height="200"></canvas>
<canvas id="testCanvas2" width="300" height="200"></canvas>
</div>
在上面的代码片段中,我创建了 2 个 canvas 并绘制了不同的矩形,然后使用 .toDataURL()
将 canvas 放入图像,并使用 _.isEqual
检查是否图片是否相同。
Expect : _.isEqual
to return false, as use ==
or ===
.
得到: _.isEqual
return true 而其他 return false.
当我使用 minfied backbone 和下划线时,有什么方法可以让我从 _.isEqual
得到 false
而不会改变 Backbone
和 Underscore
?
您可以覆盖 _.isEqual
以自定义 Image
实例的处理方式:
(function() {
var _equal = _.isEqual;
_.isEqual = function(a, b) {
if ((a instanceof Image) && (b instanceof Image))
return a.src === b.src;
else
return _equal(a, b);
};
}());
(function() {
var _equal = _.isEqual;
_.isEqual = function(a, b) {
if ((a instanceof Image) && (b instanceof Image))
return a.src === b.src;
else
return _equal(a, b);
};
}());
// Backbone inits.
var Model = Backbone.Model.extend({
defaults: {
image : null
},
initialize: function() {
this.listenTo(this, 'change', this.handleChange);
},
handleChange: function(model) {
var changes = this.changedAttributes();
if (changes) {
for (var k in changes) {
console.log(k + 'in the model changed.', this.get(k));
}
}
}
});
var testModel = new Model();
console.log(testModel.get('image'));
// Test change work
testModel.set('testval', 1);
testModel.set('testval', 2);
var canvas = document.querySelector('#testCanvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, 50, 50);
var canvas2 = document.querySelector('#testCanvas2');
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = 'red';
ctx2.fillRect(0, 0, 300, 50);
var image1 = new Image();
var image2 = new Image();
image1.onload = function() {
document.querySelector('#test').appendChild(image1);
// backbone
testModel.set('image', image1);
image2.onload = function() {
document.querySelector('#test').appendChild(image2);
testModel.set('image', image2); // This not fire
console.log("Use isEqual : ",_.isEqual(image1, image2));
console.log("Use == : ", image1 == image2);
console.log("Use === : ", image1 === image2);
};
image2.src = canvas2.toDataURL();
};
image1.src = canvas.toDataURL();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
<div id="test">
<canvas id="testCanvas" width="300" height="200"></canvas>
<canvas id="testCanvas2" width="300" height="200"></canvas>
</div>
当然,这可能会严重破坏代码中可能依赖于原始行为的其他部分。还有一个演示 http://jsfiddle.net/nikoshr/ecr16wzc/ 可以玩。
我的应用程序使用 Backbone.js
,并且在捕获图像上的更改事件时遇到一些问题,因为它使用 Underscore.js
的 _.isEqual
来决定是否更改属性,但是,它不适用于 img
:
// Backbone inits.
var Model = Backbone.Model.extend({
defaults: {
image : null
},
initialize: function() {
this.listenTo(this, 'change', this.handleChange);
},
handleChange: function(model) {
var changes = this.changedAttributes();
if (changes) {
for (var k in changes) {
console.log(k + 'in the model changed.', this.get(k));
}
}
}
});
var testModel = new Model();
console.log(testModel.get('image'));
// Test change work
testModel.set('testval', 1);
testModel.set('testval', 2);
var canvas = document.querySelector('#testCanvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, 50, 50);
var canvas2 = document.querySelector('#testCanvas2');
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = 'red';
ctx2.fillRect(0, 0, 300, 50);
var image1 = new Image();
var image2 = new Image();
image1.onload = function() {
document.querySelector('#test').appendChild(image1);
// backbone
testModel.set('image', image1);
image2.onload = function() {
document.querySelector('#test').appendChild(image2);
testModel.set('image', image2); // This not fire
console.log("Use isEqual : ",_.isEqual(image1, image2));
console.log("Use == : ", image1 == image2);
console.log("Use === : ", image1 === image2);
};
image2.src = canvas2.toDataURL();
};
image1.src = canvas.toDataURL();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
<div id="test">
<canvas id="testCanvas" width="300" height="200"></canvas>
<canvas id="testCanvas2" width="300" height="200"></canvas>
</div>
在上面的代码片段中,我创建了 2 个 canvas 并绘制了不同的矩形,然后使用 .toDataURL()
将 canvas 放入图像,并使用 _.isEqual
检查是否图片是否相同。
Expect : _.isEqual
to return false, as use ==
or ===
.
得到: _.isEqual
return true 而其他 return false.
当我使用 minfied backbone 和下划线时,有什么方法可以让我从 _.isEqual
得到 false
而不会改变 Backbone
和 Underscore
?
您可以覆盖 _.isEqual
以自定义 Image
实例的处理方式:
(function() {
var _equal = _.isEqual;
_.isEqual = function(a, b) {
if ((a instanceof Image) && (b instanceof Image))
return a.src === b.src;
else
return _equal(a, b);
};
}());
(function() {
var _equal = _.isEqual;
_.isEqual = function(a, b) {
if ((a instanceof Image) && (b instanceof Image))
return a.src === b.src;
else
return _equal(a, b);
};
}());
// Backbone inits.
var Model = Backbone.Model.extend({
defaults: {
image : null
},
initialize: function() {
this.listenTo(this, 'change', this.handleChange);
},
handleChange: function(model) {
var changes = this.changedAttributes();
if (changes) {
for (var k in changes) {
console.log(k + 'in the model changed.', this.get(k));
}
}
}
});
var testModel = new Model();
console.log(testModel.get('image'));
// Test change work
testModel.set('testval', 1);
testModel.set('testval', 2);
var canvas = document.querySelector('#testCanvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, 50, 50);
var canvas2 = document.querySelector('#testCanvas2');
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = 'red';
ctx2.fillRect(0, 0, 300, 50);
var image1 = new Image();
var image2 = new Image();
image1.onload = function() {
document.querySelector('#test').appendChild(image1);
// backbone
testModel.set('image', image1);
image2.onload = function() {
document.querySelector('#test').appendChild(image2);
testModel.set('image', image2); // This not fire
console.log("Use isEqual : ",_.isEqual(image1, image2));
console.log("Use == : ", image1 == image2);
console.log("Use === : ", image1 === image2);
};
image2.src = canvas2.toDataURL();
};
image1.src = canvas.toDataURL();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
<div id="test">
<canvas id="testCanvas" width="300" height="200"></canvas>
<canvas id="testCanvas2" width="300" height="200"></canvas>
</div>
当然,这可能会严重破坏代码中可能依赖于原始行为的其他部分。还有一个演示 http://jsfiddle.net/nikoshr/ecr16wzc/ 可以玩。