【问题标题】:JS object eventsJS 对象事件
【发布时间】:2016-10-16 15:00:12
【问题描述】:

我已经使用 JS 很长时间了,但我只是开始正确使用对象。

我正在使用画布创建图像生成器,然后您可以将其下载为 png。用户可以使用输入框向图像添加文本。我已经把它变成了一个 JS 对象,这样我就可以在一个页面上创建它的多个实例。一切正常,除了我的事件监听器更新文本。

输入框由传递给函数的参数创建,然后添加一个 keyup 事件,以便画布可以随着用户键入而更新。这一切正常,除了我不知道如何告诉 keyup 事件它应该更新什么 JS 对象。

这是我的代码:

function Canvas_to_img( name, container, image, height, width, content_areas ){
    // Assign params to object
    object = this;
    this.name = name;
    this.container = container;
    this.image = image;
    this.height = height;
    this.width = width;
    this.content_areas = content_areas;

    // Prepare image
    var imageObj = new Image();
    imageObj.src = image;

    // Add canvas div
    container.prepend('<div class="canvas canvas--' + name + '"></div>')

    // Add temp canvas div
    container.append('<div class="canvas-temp canvas-temp--' + name + '"></div>')

    // Add canvas wrapper
    var wrapper = new Concrete.Wrapper({
      container: container.find('.canvas')[0],
      width: width,
      height: height
    });

    // Add BG and Text layers
    var bgLayer = new Concrete.Layer();
    var textLayer = new Concrete.Layer();
    wrapper.add(bgLayer).add(textLayer);

    // Add image to BG layer
    imageObj.onload = function() {
        bgLayer.sceneCanvas.context.drawImage(imageObj,0,0, width, height);
    };

    // Set up input areas and event listeners
    for (key in content_areas){

        for (subkey in content_areas[key].fields){
            name_field = content_areas[key].fields[subkey].name;
            name_layer = content_areas[key].fields[subkey].name;

            // Add input fields for text layer
            container.prepend('<div class="field-set__item">\
                <span class="field-set__label">' + name_field +'</span>\
                <input data-object="'+object+'" data-area="' + key + '" data-name="' + name + '" data-field="' + subkey + '" class="field-set__input ' + name_field + '" id="text1" type="text">\
            </div>');

            $( "."+name_field ).keyup(function() {
                area = $(this).data('area');
                field = $(this).data('field');
                object = $(this).data('object');
                console.log(object);
                value = $(this).val();
                content_areas[key].fields[subkey].name;
                //content_areas[area].fields[field].value = value;
                OBJECTNAME.updateContent(area, field, value)
                OBJECTNAME.updateCanvas(wrapper);
            });
        }
    }

    container.append('<a href="#" id="download--' + name +'" class="button download download--' + name + '">Download</a>');

    $('body').on('click', '.download--' + name, function(e) {
        var dataURL = $('.canvas-temp--fb-banner canvas')[0].toDataURL('image/png');
        $(this).attr('download', 'test.png');
        document.getElementById('download--' + name).href = dataURL;
    });
}

Canvas_to_img.prototype = {
    updateContent: function(area, field, value){
        this.content_areas[area].fields[field].value = value;
    },

    updateCanvas: function(wrapper) {
        $('.canvas-temp--'+this.name+' canvas').remove();
        wrapper.layers[1].destroy();

        var textLayer = new Concrete.Layer();
        wrapper.add(textLayer);

        content_areas = this.content_areas;

        for (key in content_areas){
            textLayer.sceneCanvas.context.fillStyle = content_areas[key].colour;
            textLayer.sceneCanvas.context.font = "bold 24px Open Sans";
            textLayer.sceneCanvas.context.textAlign = content_areas[key].alignment;
            layer_content = '';
            for (subkey in content_areas[key].fields){
                //console.log(content_areas[key].fields[subkey]);
                layer_content += content_areas[key].fields[subkey].prepend + " ";
                layer_content += content_areas[key].fields[subkey].value;
                layer_content += content_areas[key].fields[subkey].append + " ";
                //console.log(layer_content);
            }
            textLayer.sceneCanvas.context.fillText(layer_content, content_areas[key].position_x, content_areas[key].position_y);
        }

        //ctx.fillText($(this).val(), cnvs.width/2, 300);
        // textLayer.sceneCanvas.context.fillText('Test', 325, 300);
         var canvas = wrapper.toCanvas({
            pixelRatio: 1
        });
        //console.log(canvas.canvas);
        $('.canvas-temp--'+this.name).append(canvas.canvas);
    },
    update: function(){

    }
};



var content_areas = {
    1: {
        position_x: 425,
        position_y: 300,
        alignment: 'center',
        colour: '#fff',
        font: 'Open Sans',
        size: '24px',
        weight: 600,
        fields: {
            field_1: {
                name: 'date',
                value: '',
                prepend: '',
                append: ','
            }, 
            field_2: {
                name: 'venue',
                value: '',
                prepend: '',
                append: ''
            }
        }
    }
}

var content_areas_2 = {
    1: {
        position_x: 425,
        position_y: 300,
        alignment: 'center',
        colour: '#fff',
        font: 'Open Sans',
        size: '24px',
        weight: 600,
        fields: {
            field_1: {
                name: 'date',
                value: '',
                prepend: '',
                append: ','
            }, 
            field_2: {
                name: 'venue',
                value: '',
                prepend: '',
                append: ''
            },
            field_3: {
                name: 'time',
                value: '',
                prepend: '',
                append: ''
            }
        }
    }
}

var facebook_banner = new Canvas_to_img('fb-banner', $('.banner-container'), 'http://localhost:1234/images/mainsite5/bb-fb-cover.jpg', 315, 851, content_areas);
var facebook_banner_2 = new Canvas_to_img('fb-banner-2', $('.banner-container-2'), 'http://localhost:1234/images/mainsite5/bb-fb-cover.jpg', 315, 851, content_areas_2);

这些是需要与对象关联的函数调用:

OBJECTNAME.updateContent(area, field, value)
OBJECTNAME.updateCanvas(wrapper);

我可能需要将此事件监听器链接到对象本身?我不知道该怎么做。

【问题讨论】:

标签: javascript object


【解决方案1】:

我发现将实例保存到元素很有用。您可以通过获取此处分配的实例来执行此操作:

var facebook_banner = new Canvas_to_img('fb-banner', $('.banner-container'), 'http://localhost:1234/images/mainsite5/bb-fb-cover.jpg', 315, 851, content_areas);

并将其设置为其元素的数据属性:

$('.banner-container').data('canvas_to_img', facebook_banner);

现在您可以在需要时获取该实例:

$('.banner-container').data('canvas_to_img');

或者,如果您已经在该元素的上下文中:

$(this).data('canvas_to_img');

【讨论】:

  • 谢谢,这已经奏效了,我现在正在使用它。感谢帮助。感觉应该有一种方法可以做到这一点,而不必将对象传递给元素并返回......
【解决方案2】:

updateContentupdateCanvas 是您在代码底部创建的对象的原型。通常,您将使用this.updateContent(area, field, value) 访问那些。 但是您在回调函数中,所以this 指的是该函数的范围。

在您的代码的前面,您设置了object = this;(为什么是对象全局b.t.w.?),因此您已经将this 存储在一个您应该可以在回调中访问的变量中。所以你的代码应该是:

object.updateContent(area, field, value); 等 // 对象是你的this

Here 是另一个类似但经过简化的问题。

【讨论】:

  • 如果我使用object,我只会得到最后一个创建的对象,因此所有更改都适用于最后一个图像。我试过this.object = this,但后来被分配给了对象,所以我不能在回调函数中引用它。
  • 那是因为对象在全局范围内,这无论如何都是不好的。尝试将var that = this; 作为Canvas_to_img 函数的第一行。然后你就可以这样做了。updateContent(area, field, value);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多