JSFF或JSF页面加载时触发JavaScript之方法

现象一

最近在项目中遇到这么一个问题,有些页面元素是在页面加载时通过JavaScript动态渲染而成。当生成这些元素的JavaScript脚本被放置于JSPX文件中时,界面渲染没有问题。但是当我们把生成这些页面元素的JS脚本放到JSFF时就会发现,JS脚本只在我们进入TaskFlow的第一个View被执行了,进入后续View时,后续View的JS代码加载和执行。

分析

通过分析,发现当进入TaskFlow的第一个View时,第一个View中通过<af:resource/>标签引入的JS代码能成功被添加到页面上,而且页面的onload事件也被执行,所以页面元素渲染成功。

但是当从第一个View流转到后续View时,后续View中通过<af:resource/>标签引入的JS代码则没有被加入页面中,所以页面元素都无法渲染。但是如果此时我们刷新页面,页面上的元素又能正确展现。这是因为刷新后ADF重新生成页面的HTML代码,重新解析了后View中的<af:resource/>标签,并将相关的代码引入页面。

解决

在<af:resource/>标签外套用<af:panelGroupLayout/>,这样resource就会每次都被包含到页面中。

现象二

解决了上一个问题,现在TaskFlow中所有View在展现时,JavaScript代码都能正确地被引入页面,并被执行以正确地生成页面元素。但是很快我发现了另外一个问题,那就是JavaScript代码只能在第一次展示View时成功被调用。如果我们从一个View流转到另一个View,然后再次流转回来的话,onload事件的JavaScript就不会被执行了。

分析

ADF渲染了某个View后,该View就会有缓存,再次访问时就不会再次渲染并触发onload事件。我尝试设置了TaskFlow的Refresh配置,但是无果。

问题的关键是现在无法保证每次进入View时都能触发onload事件,既然客户端脚本不行,那么是否能够通过服务端的方式在页面加载时激活相应的JavaScript代码进行元素的渲染呢?使页面在加载时能触发后台的一个Java方法,然后在Java方法内触发JS方法(关于如何在Java中调用JS,请参考我的这篇文章)。按照这个思路,我们可以通过在页面添加Executable来实现。通过搜索我发现网上的确也有人遇到类似的问题,并通过这种方法解决。但是通过Executable来实现有个缺点,就是需要生成自定义的Java Bean Data Control以及配置起来比较繁琐(需要为每个页面配置Method Binding以及Executable)。

解决

经过不断的尝试,最后,我想到了一个简化的方法:

1. 在View中添加一个<af:outputText/>标签;

2. 将<af:outputText/>的Value绑定到一个bean的属性#{myBean.dummy};

3. 其实,无需在myBean中定义dummy属性,只需定义一个getDummy()方法,并在其中添加调用JS代码的逻辑;

每当JSFF展现时ADF会重新执行所有的EL表达式,包括#{myBean.dummy},这样在getDummy()中的逻辑就会被执行,相应的JS方法也会被调用。这样我们的需求就实现了。但是,我觉得将JS的调用逻辑完全放在Bean中完成可能会比较死板。如果我们需要更改调用JS的逻辑,就必须要修改Bean的方法。最后我将调用JS的逻辑进行修改,使其调用脚本内容指向前台<af:outputText/>标签的shortDesc属性:

    private RichOutputText scriptSetting; //OutputText的binding变量

 

    public String getDummy() {

        String script = scriptSetting == null ? "" : scriptSetting.getShortDesc(); //获取脚本内容

        invokeJavaScript(script);//调用JS

        return "";

    }

以后如果某个页面需要在加载时调用JS脚本,只需要做下面3步:

1. 在TaskFlow中注册myBean;

2. 在页面中放置如下代码;

<af:outputText  shortDesc="youJSFunction();"

                   value="#{myBean.dummy}" id="scriptControl"

                   binding="#{myBean.scriptSetting}"/>

3. 修改shortDesc属性值为所需要的JS代码。

示例的源代码请在这里下载,所使用的JDeveloper版本为11.1.1.6.0。

只要思想不滑坡,办法总比问题多 :)元芳,你怎么看?

转载自:http://blog.sina.com.cn/s/blog_671b3b1001018vr3.html

时间: 2024-08-23 11:52:55

JSFF或JSF页面加载时触发JavaScript之方法的相关文章

如何自动在html页面加载时动态改变div等元素的高度和宽度

这里需要用到jquery + css.原理是在页面加载时用javascript去动态改变一个class的高度和宽度.这样结合javascript能动态获取浏览器/页面的高度和宽度,从而使得div能动态的跟随浏览页面的大小变化而变化并且不影响高宽比.下面的代码创建一个手机页面,每一行三个图片分占33%,每个图片div的高和宽会随着浏览器的大小变化而自适应. <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"

Javascript在页面加载时的执行顺序【转】

一.在HTML中嵌入Javasript的方法 直接在Javascript代码放在标记对<script>和</script>之间 由<script />标记的src属性制定外部的js文件 放在事件处理程序中,比如:<p onclick="alert('我是由onclick事件执行的Javascript')">点击我</p> 作为URL的主体,这个URL使用特殊的Javascript:协议,比如:<a href="

ASP.NET中页面加载时文本框(texbox控件)内有文字获得焦点时文字消失

代码如下: <asp:TextBox ID="TextBox1" runat="server" Height="26px" MaxLength="10" Width="166px" Text="请输入用户名" OnFocus="javascript:if(this.value=='请输入用户名') {this.value='';this.style.color='#000

页面加载时让其显示笼罩层与加载等待图片

页面加载时让其显示笼罩层与加载等待图片(结局比较完美,过程很坎坷,所以一定总结整理下,备用): 用了ajax异步,是因为js内容不能即时的显示出来,因为js是单线程,要把队列中的任务执行完后才会执行刚才对js的处理 要用beforeSend,complete的时候必须要用ajax异步 beforeSend: function () {},//程序一开始便会执行该函数,使用该方法必须使用异步ajax complete: function () {},//complete在success或error

页面加载时的 Loading 效果

//页面加载时的 Loading 效果 $(window).load(function () { window.setTimeout(function () { $('body').removeClass('loading'); }, 1000); }); 上面的JS部分: HTML 部分 <body class="loading"> <div class="main"> </div></body> css .load

jquery 页面加载时获取图片高度

$(function () { $(window).load(function(){ alert($('img').height()); }); }); jquery 页面加载时获取图片高度

aspx页面加载时清掉缓存

今天遇到一个问题,账户退出后登陆其他账户仍然显示上个账户用户名, 用了session.clear();session.abandon();context.Session["姓名"] = "";都不管用 最后在aspx页面加载时加上下面代码就可以了 Response.Expires = 0;Response.Cache.SetNoStore(); Response.AppendHeader("Pragma", "no-cache"

页面加载时的div动画

用@keyframes(动画),实现页面加载时的div动画(不要用js控制,因为当页面加载的时候,js还不一定可以使用) 可以在https://daneden.github.io/animate.css/参考所需要的动画效果 div{ opacity:0; } @keyframes fadeInLeft { from { opacity: 0; transform: translate3d(-100%, 0, 0); } to { opacity: 1; transform: translate

页面加载时遮罩效果

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title>页面加载时遮罩效果</title>        <script type="text/javascript" src="js/jquery-1.4.1.min.js"></script>