手动触发的Javascript事件不会传播到iFrame上下文中的元素

时间:2014-11-12 14:28:27

标签: javascript jquery iframe javascript-events

我正在研究一种WYSIWYG设计器,它允许最终用户通过[input type =“color”]字段选择颜色。此界面左侧有输入,右侧是指向生成预览的iframe。通常,当单击输入并更改颜色时,它会调用函数更新(通过输入字段上的更改事件的骨干视图绑定)。然后,此更新功能会更改iFrame中的CSS值,以进行实时预览。这工作正常。

但是,我正在构建一个单元测试页面,主要是测试将输入字段更改为某种颜色确实会改变预览中的颜色。基本上这样:“将输入更改为PINK。预览中相应的CSS选择器是否更改为PINK?”

单元测试页面的结构是通过iFrame加载设计器。所以现在我们有:

  • 第0层:单元测试报告
  • 第1层:变色输入
  • 第2层:实时预览

所以这就是问题所在: 单元测试运行时,成功更改输入字段的值,但后续更改事件似乎没有被视图捕获,因此实时预览不会更新。

以下是代码:

for (i in testable) {
    item = testable[i];
    item.element.val(tempColor);
    item.element.trigger('change');
}

如果我将其拉出测试模块的范围并使用浏览器的控制台,则此代码具有相同的效果(输入更新,但从不调用触发器):

$("#testFrame").contents().find('input#cat_RowColoralternate').val('#AAEFCC').trigger('change')

为了证明事件存在并确实有效,如果我在没有测试层的情况下直接加载它(例如,直接加载应用程序),这段代码就可以正常工作。

$(document).find('input#cat_RowColoralternate').val('#AAEFCC').trigger('change');

唯一的区别是额外的iFrame层,所以我的理论是事件没有从第0层传播到第1层。

1 个答案:

答案 0 :(得分:3)

我不相信你可以通过这种方式跨帧触发jQuery事件。对.trigger()的调用发生在父框架中,因此在iframe的jQuery对象中无法正常工作。

相反,您需要在iframe中获取jQuery对象,并在那里执行触发器:

var framejQuery = $('#testFrame').get(0).contentWindow.$;
framejQuery('input#cat_RowColoralternate').val('#AAEFCC').trigger('change');