论坛首页 Web前端技术论坛

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

浏览 10668 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-11-04  
我们的门户的静态页面是用自定义标签,freemarker模板等组成的,自己定义好取数规则,没有ID重复的问题
0 请登录后投票
   发表时间:2011-11-04  
可执行 写道
最近在为公司开发一个通用的门户发布平台,项目做了一大半了,突然遇到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生成时间戳给后台,然后后台DOM节点的ID把这个时间戳加上达到唯一,后台用模板引擎,很好解决多实例问题的。
0 请登录后投票
   发表时间:2011-11-04  
参考JSF的设计思想。
0 请登录后投票
   发表时间:2011-11-05  
hu437 写道
namecepace,在门户(portal)如果是使用的portlet,则每一个portlet会有一个namespace,如果同一个portlet在页面中出现多次,这个namespace也要生成不一样的

这位正解。portlet中是有namespace的。可以将id加上namespace,如id="${ns}name"
0 请登录后投票
   发表时间:2011-11-05  
是按照面向对象的方式封装的组件吗,js里有this关键字,多实例冲突应该很好解决。
0 请登录后投票
   发表时间:2011-11-05  
clue 写道
可执行 写道
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>


你那两段代码并不是相同的,其中“a1”和“a2”不同。

这里的js是不知道有a1、a2存在的,除除非你有什么方法写代码自动拿到“a1”和“a2”
0 请登录后投票
   发表时间:2011-11-05  
lhgyy00 写道
你可以看看Ext是怎样封装portlet的,类似,封装组件对象,用命名空间,我们现在的门户就是用的portlet,基本没问题。


那是因为他们的组件都已经做好了,可以提前避免,我们这个要求可以开发新的组件放进去,所以会产生冲突。
0 请登录后投票
   发表时间:2011-11-05  
__游乐场 写道
用iframe就等着哭吧, 到时候卡死你, 内存泄漏搞死你. 加入命名空间来保持ID唯一就好了.


请问你所说的“命名空间”原理是什么,怎么实现?
0 请登录后投票
   发表时间: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生成时间戳给后台,然后后台DOM节点的ID把这个时间戳加上达到唯一,后台用模板引擎,很好解决多实例问题的。



可以具体一点吗?我感觉你的思路好像可行。

0 请登录后投票
   发表时间:2011-11-06  
其实这个问题应该还是好解决的吧!你这个有个规律,就是每个脚本代码段都是大控件div的子元素,你只需要通过每个脚本段代码去获取它的父元素,然后再以父元素为根结点处理后续逻辑就可以了,至于要不要id都无所谓了。就好像相对引用与绝对引用,基于id相当于绝对引用,每个页就一个,你这个地方用相对引用就好了。
0 请登录后投票
论坛首页 Web前端技术版

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