我们通过createPopup创建的popup对象包含了一个document属性,document其实就是html的容器。MSDN说:构建popup的DHTML可以存储在其父document或其他的document中。这个话真是让人不明白,其实就是说我们可以使用popup.document.body去append别的DHTML内容,比如:popup.document.body.innerHTML = '...'或popup.document.body.appendChild(...)。这里又遇到了popup的一些怪异的特性,我们发现:
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
上面的popdoc和popwindoc引用虽然不同,不过执行效果却相同,都能按我们预期的效果修改popup。可是接下来我们发现popup.document.body的appandChild方法和innerHTML属性向popup里添加DHTML内容的效果就大不同了,这个不同和给我带了很多的麻烦,使菜单的逻辑数据(JavaScript构建的菜单类)与UI表现(HTML元素构建的菜单的可视外观)以及它们之间的事件传递变得乱糟糟的
![emsad.gif](/Emoticons/emsad.gif)
我们有两个方法向popup里添加html内容,一个是使用popup.document.body的innerHTML直接把html代码赋到body中去;另一个办法是使用popup.document.body的appendChild方法对dom进行操作。这里要注意,必须使用popup自己的document对象来创建DHTML元素,才能使用appendChild来添加。比如我上面代码中的popdoc和popwindoc虽然引用不相等,但是确实是popup的doucment对象,使用他们来createElement得到的对象,才能被appendChild到popup里去。如果是使用doc来createElement得到的对象,在popup.docuemnt.body上去appendChild会得到一个运行时错误:Error: Invalid argument.。
为什么啰里啰唆说了半天appendChild方法和innerHTML属性呢?因为他们各有各的好处,如果使用appendChild这种方式,我们可以在创建菜单类的数据的时候,使菜单的逻辑数据(JavaScript实现的类)和UI显示元素(HTML)之间彼此引用起来,这样在我们处理菜单事件的时候,会使程序和整个执行结构都变得比较清晰(这个在菜单处理事件的时候,我会再详细说)。这样一说,我们当然应该使用这种方法来append我们的菜单的内容了,可是我们又遇到了popup一个让人抓狂的问题
![emangry.gif](/Emoticons/emangry.gif)
![ContextMenu1.gif](https://i-blog.csdnimg.cn/blog_migrate/569869a80cbf410cab3eecc40a4b0d06.gif)
所以不得不放弃了appendChild方法的使用,改用popup.document.body.innerHTML直接赋值html的办法,可是这种方法就不能在对象引用关系上建立菜单逻辑数据和UI元素之间的联系,因为对象引用虽然能被存储在html元素的属性中,可是当以字符串方式来复制html元素时,html元素上attach的事件和属性里存放的对象引用就都丢失了,所以只能使用另外的办法来关联他们。于是我们实现了一个叫__MenuCache__的类似hash table的全局类来管理它们之间的一一对应关系。
to be continued ...