Famo.us:函数调用作为表面内容中的 HTML 链接

Famo.us: Function Calls as HTML Links in Surface Content

我正在尝试通过单击表面上的 HTML link 来调用函数。 这不符合预期:

define(function(require, exports, module) {
    var Engine = require("famous/core/Engine");
    var Surface = require("famous/core/Surface");
    var mainContext = Engine.createContext();

    var surf = new Surface({
        size: [100, 50],
        content: '<a href="#" onclick="test()">Click me</a>',
        properties: {
            backgroundColor: '#00FF00'
        }
    });

    function test(){
        alert('Test!');
    }

    mainContext.add(surf);
});
var test = function(){
    alert('Wrong call...');
}

我想让它调用第一个 "test()" 函数,但它所做的只是调用外部函数。

为了得到它,我尝试了这样的事情:

var testObject = define(function(require, exports, module) {
(...)
    var surf = new Surface({
        size: [100, 50],
        content: '<a href="#" onclick="testObject.test()">Click me</a>',
        properties: {
            backgroundColor: '#00FF00'
        }
    });
(...)
};

然而这也没有用。关于如何让它调用正确的函数有什么想法吗?

您的问题与 JavaScript 如何处理范围有关。

虽然你的内部''test''函数在"define,"的范围内,但Famo.us呈现的html元素可以看到的是外部' 'test'' 函数。

以下是更多eloquent将事件绑定到表面的方法:

var surf = new Surface({
    size: [100, 50],
    content: '<p>Click me</p>',
    properties: {
        backgroundColor: '#00FF00'
    }
});

test = function() { 
    alert("Test!"); 
};

surf.on("click", test());

更新评论

下面是一个替代方案,但不好的做法,你也可以这样做。这本身还不错,但这并不是真正的最佳实践:

var surf = new Surface({
    size: [100, 50],
    content: '<p onclick="|*Your Exported Module Name*|.test()">Click me</p>',
    properties: {
        backgroundColor: '#00FF00'
    }
});

surf.test = function() { 
    alert("Test!"); 
};

正如你在上面看到的,通过显式地赋予test()方法的surf变量所有权,它为我们节省了可能两行可读的JS 并基本上将标记与业务逻辑代码结合起来。因为您使用的是 RequireJS 并且 DOM 元素中的 onclick 属性只能很容易地看到全局 Javascript 范围内存在的东西,所以我们必须一直深入到正确的 RequireJS 的正确变量中模块以访问它的方法。

如果 surf 变量被删除或以任何方式修改(别让我开始)你的代码现在很容易停止正常工作,因为你的 html 元素取决于存在一个名为 surf 的 javascript 变量和一个名为 test 的方法,因此您的应用程序成为维护噩梦...

所以注意安全。 Famo.us 是一个 Javascript 渲染引擎,恰好渲染到 DOM,但这并不一定意味着所有旧的 DOM 原则仍然可以使用并保持优雅就像它们在传统网页中一样。祝你好运:)

捕获点击目标的点击事件,而不是捕获Surface的点击事件。使用标识符 (id) 而不是方法函数调用来标识我们要调用的 link 函数。

完整代码如下:Example on jsBin

首先我们跟踪目标表面内的点击并调用函数来检查它是否是 link。如果我们点击 link,我们将发出一个传递目标 href 的事件。

var surf = new Surface({
    size: [100, 200],
    content: '<a id="test" href="#test">Click me</a><br/><a id="test1" href="#test1">Click me</a><br/><a id="test2" href="#test2">Click me</a><br/><a id="test3" href="#test3">Click me</a>',
    properties: {
        backgroundColor: '#00FF00',
        textAlign: 'center',
        borderRadius: '10px',
        lineHeight: '40px'
    }
});

surf.clickNullifier = function (e) {
    if (e.target && e.target.nodeName == 'A' && e.target.id) {
        console.log('id', e.target.id);
        console.log('href', e.target.href);
      switch (e.target.id) {
        case 'test':
          test.call(this, 'called test');
          break;
        case 'test1':
          test.call(this, 'called test1' );
          break;
        case 'test2':
          test.call(this, 'called test2');
          break;
        case 'test3':
          test.call(this, 'called test3');
          break;
        default:
      }
    }
    e.preventDefault();
    return false;
}.bind(this);

surf.on('deploy', function () {
    console.log('deploy',this._currentTarget);
    // sets up the click function on the surface DOM object
    this._currentTarget.onclick = this.clickNullifier;
});

function test(msg) {
    this.backSurface.setOptions({content: msg});
}