强调# 39;s _.isEqual不能区分两个图像

Underscore's _.isEqual can't distinguish 2 images

本文关键字:图像 两个 不能区 isEqual 强调      更新时间:2023-09-26

我的应用程序使用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个画布并绘制不同的矩形,然后使用.toDataURL()将画布放入图像,并使用_.isEqual检查图像是否相同。

期望:_.isEqual返回false,如使用=====

Get: _.isEqual返回true而其他返回false。

当我使用简化的骨干和下划线时,是否有任何方法可以让我从_.isEqual中获得false,而不改变BackboneUnderscore ?

您可以重写_.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/。