如何在事件处理程序中更改传递的变量

时间:2017-05-26 23:40:43

标签: javascript jquery javascript-events reference event-handling

我想知道是否有办法通过处理事件来改变“外部”变量

function generateHTML()
{
    var html = '';

    // Some html generating code
    html += '<b>John Doe</b>';

    $(document).trigger('html:generating', html);

    // Do more hardcoded stuff with html

    $(document).trigger('html:generated', html);

    return html;
}

$(document).on('html:generating', function(e, html) {
    html = '<span>' + html + '</span>';
});

$(document).on('html:generated', function(e, html) {
    console.log(html);  // prints <b>John Doe</b>
                        // expected <span><b>John Doe</b></span>
});

generateHTML();

这在处理Mustache(或任何其他模板库)动态html代码时非常有用。

3 个答案:

答案 0 :(得分:1)

如果您正在谈论通过引用传递HTML,有一种方法可以做到这一点。作为函数参数传递的所有内容都是按值传递的,但是如果传递一个对象,则对象属性仍会指向原始值,因为指针会被复制。所以,你可以这样做:

function generateHTML()
{
    var container={html: ''};

    // Some html generating code
    container.html += '<b>John Doe</b>';

    $(document).trigger('html:generating', container);

    // Do more hardcoded stuff with html

    $(document).trigger('html:generated', container);

    return container.html;
}

$(document).on('html:generating', function(e, container) {
    container.html = '<span>' + container.html + '</span>';
});

$(document).on('html:generated', function(e, container) {
    console.log(container.html);
});

generateHTML();

答案 1 :(得分:1)

您可以将变量移动到更高的范围(如@potter建议的那样)。如果您创建对象可能更容易使用,但如果您执行非常简单的任务可能没有必要。

理想情况下,“渲染器”代码将在其自己的文件中重复使用。

请参阅下面的代码变体以获取基本示例。

// Some Object
var Renderer = function(scope, args) {
	var self = this;
  var scope = $(scope) || $(document);
  var html = args.html || "";
  
  self.setHtml = function(setHtml){
  	html = setHtml;
  }
  
  self.getHtml = function(){
  	return html || "";
  }
  
  self.generateHTML = function() {
    scope.trigger('html:generating', self.getHtml());

    // Do more hardcoded stuff with html
		
    scope.trigger('html:generated', self.getHtml());
  }
  return self;
}


// Your Code
var contentScope = document;
var contentRenderer = new Renderer(contentScope, {html: "<b>John Doe</b>"});

$(contentScope).on('html:generating', function(e, html) {
    contentRenderer.setHtml('<span>' + html + '</span>');
});

$(contentScope).on('html:generated', function(e, html) {
    console.log(html);  // prints <b>John Doe</b>
                        // expected <span><b>John Doe</b></span>
});

contentRenderer.generateHTML();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

答案 2 :(得分:0)

您可能想了解闭包的工作原理。 (所有javascript函数都是闭包)

对于这个特定问题,您所要做的就是将html变量的声明移到函数之外,进入更高的范围。然后,如果您仍想在事件处理程序中传递变量,则需要使用其他名称。

var outerHtml = '';
function generateHTML() {    
    // Some html generating code
    outerHtml += '<b>John Doe</b>';

    $(document).trigger('html:generating', html);

    // Do more hardcoded stuff with html

    $(document).trigger('html:generated', html);

    return outerHtml;
}

$(document).on('html:generating', function(e, html) {
    outerHtml = '<span>' + html + '</span>';
});

$(document).on('html:generated', function(e, html) {
    console.log(outerHtml);  // prints <b>John Doe</b>
                        // expected <span><b>John Doe</b></span>
});

generateHTML();