论坛首页 Web前端技术论坛

第一次遇到javascript多实例冲突问题,提供部分解决方案

浏览 10791 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-11-01   最后修改:2011-11-05
最近在为公司开发一个通用的门户发布平台,项目做了一大半了,突然遇到javascript多实例冲突问题,蛋都碎了!!

原理是这样的:

门户以页面为大的容器,每个页面里面又有多个小的容器(暂且叫它控件容器),控件容器是用来放控件的,后台语言(java)在生成页面时选择对应的控件放到对应的控件容器中。

控件其实就是一大段代码,其中包括html、css、javascript代码,控件中的代码只贡空间本身用,所以后台语言只要把控件所有代码打印到空间容器中,控件中的css和javascript就会把控件表现出来。

问题来了,当同一个控件在同一个页面出现多次时,javascript就无法正常运行了,原因是javascript可能通过id来获取DOM节点,而同一个控件被在同一个页面中有多个,这就意味中存在多个相同的id标签,然后就乱了。。。


目前在考虑的解决方案:

(1)在每个控件容器中加iframe标签并以页面的形式引入控件,但是这样的话一个页面中包含了多个页面,不知道这个样会不会有什么问题,而且iframe本身处理起来不知道会不会出现瑕疵,比如不同浏览器下会不会出现滚动条什么的。。

(2)通过后台语言给每个控件容器打印一个唯一的id,要求控件中的javascript在DOM操作时都以唯一id来选择标签。但是要怎样给这个id而只让本容器中的javascript拿到这个id呢?例如下面:


page页面内容:(用两个div表示两个控件容器)
——————————————————————————————————————

<!-- id中的1是后台语言输出的唯一标记 -->
<div id="1">
    <script>
        这里需要一行javascript代码
    </script>
</div>


<!-- id中的2是后台语言输出的唯一标记 -->
<div id="2">
    <script>
        这里需要一行javascript代码
    </script>
</div>

——————————————————————————————————————

在页面中标记“这里需要一行javascript代码”的地方应该是一段相同的代码,如何让这段代码执行时拿到其对应的id标签?(id的值是后台语言输入的,所以对javascript是未知的)


详细方案还在讨论中,公司一大帮人跟后面碎蛋中 。。。。


很多热心的朋友理解错了,上面那两处js代码必须一摸一样,不可以写类似getElementById("1")、getElementById("2")这样的的代码,那样就不一样了,应为代码本身是跟着组件被放进去的所有是一样的,它并不知道自己对应的id是1或2,必须想一个方法自动去拿到对应id





   发表时间:2011-11-02  
这和C程序里的全局变量一个道理,当程序很小(页面简单)时,用全局变量无所谓,只有你一个人用。
当程序分模块变得很大(页面复杂,由多组件组成)时,用全局变量就会破坏封装,增加耦合度。
所以你看现在都不提倡使用全局变量,同理于RIA下的html id,就算要用也要动态生成,各实互不干扰。
0 请登录后投票
   发表时间:2011-11-02  
namecepace,在门户(portal)如果是使用的portlet,则每一个portlet会有一个namespace,如果同一个portlet在页面中出现多次,这个namespace也要生成不一样的
0 请登录后投票
   发表时间:2011-11-03  
为什么你控件容器没有一个名称
0 请登录后投票
   发表时间:2011-11-03  
hu437 写道
namecepace,在门户(portal)如果是使用的portlet,则每一个portlet会有一个namespace,如果同一个portlet在页面中出现多次,这个namespace也要生成不一样的


你认真看,每个portlet的确是后台语言给了唯一的id啊,但是相同的代码如何拿到各自对应的id呢?你试着写代码来拿就发现很难做到了。。
0 请登录后投票
   发表时间:2011-11-04  
不明所以
为嘛相同代码要输出多次呢?
我的观点,函数,参数
或者闭包
iframe的滚动条好说,CSS设置一下就OK,但是自动高度是个麻烦,跟父页面的交互也麻烦,里面的内容漂不出外面
0 请登录后投票
   发表时间:2011-11-04  
可执行 写道
hu437 写道
namecepace,在门户(portal)如果是使用的portlet,则每一个portlet会有一个namespace,如果同一个portlet在页面中出现多次,这个namespace也要生成不一样的


你认真看,每个portlet的确是后台语言给了唯一的id啊,但是相同的代码如何拿到各自对应的id呢?你试着写代码来拿就发现很难做到了。。

很难吗?我觉得你们先要处理的是JS代码的组件化,比如:

<script src="widget组件JS"></script>

<!--组件1-->
<div id="a1"></div>
<script>
new widget({ id : "a1" });
</script>

<!--组件2-->
<div id="a2"></div>
<script>
new widget({ id : "a2" });
</script>
0 请登录后投票
   发表时间:2011-11-04  
用iframe就等着哭吧, 到时候卡死你, 内存泄漏搞死你. 加入命名空间来保持ID唯一就好了.
0 请登录后投票
   发表时间:2011-11-04  
1.iframe不推荐,我自己也不用,具体原因不明,个人不喜欢。
2.你自己后台统一id
3.用name,不用id. jquery中差不多这样
    var p = $('#p');//这里可以把p这个容器保存下来,找里面的元素可以直接find,提高效率
    p.find('[name=xxx]');//这里直接找
0 请登录后投票
   发表时间:2011-11-04  
你可以看看Ext是怎样封装portlet的,类似,封装组件对象,用命名空间,我们现在的门户就是用的portlet,基本没问题。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics