?Javascript不比Java,没有import关键字(据说Javascript2.0将加入Import和命名空间)。在网上查了很多别 人写的Import函数的代码,通常都是直接在HTML里插入script元素来实现。这种方式无法实现同步导入,即import函数调用的下面无法马上 使用导入JS里面的变量。
下面的代码将使用AJAX方式来实现Import功能,可以实现同步导入。调用方式很简单,在JS代码开始处调用$import()函数就可以了。
另外本代码还集成了CSS的导入,虽然很简单但也很有用。因为如果你编写了一个JS文件来实现某种控件,你肯定不希望使用你的JS文件的人还要在他自己的代码里引入你的CSS文件。所以你可以使用本代码里的$import函数在你的JS文件中引用你的CSS文件。
最后,本代码还提供了一个很振奋的功能,即为你导入的JS文件中的全局变量加上命名前缀。我们在很多高级语言中都可以做到这一点,如引用JAVA的JSP标签库,<%@ taglib uri="http://java.sun.com/jsp/jstl/core " prefix="c"%>,这个库里面的内容可以用前缀C与其他标签库区分开来。本代码也提供了类似的功能,如:$import("../lib/head.js","h")。之后就可以用h.XXX来引用head.js里定义的函数和变量了。
代码如下:
/** * 这个JS文件提供了命名空间、JS文件导入功能。 注:import本身是个关键字,不能用来做变量函数名 * 通过本代码可以导入Javascript文件,可以使用绝对URL和相对URL作为路径 $import("../lib/head.js"); * $import("head.js"); 可以导入CSS文件 $import("head.css"); * 导入Javascript文件时,可以为导入文件里所定义的全局变量增加前缀,如: $import("prototype.js","p"); var * mydiv = p.$("myDiv"); * 但只有用var定义的全局变量和全局函数将增加前缀,而没有用var定义的变量将被视为必须要为全局的变量,不增加前缀 * * @author 由月 */ var Import = {}; Import.importedJSFiles = []; Import.importingJSFiles = []; Import.importedCSSFiles = []; Import.$import = function(url, prefix) { // 检查参数合法 if (url == null || url == "") return; // 获取导入文件的完整URL var fullUrl = Import.getFullPathFromUrl(url); // 先将此URL放入正在导入的列表中 Import.addImportingFile(fullUrl); // 判断导入的是JS文件还是CSS文件 if(Import.getFileType(fullUrl) == ".js"){ Import.importJS(fullUrl, prefix); } else { Import.importCSS(fullUrl); } // 将URL从正在导入列表中移除,并加入已导入列表 Import.addImportedFile(fullUrl); }; Import.importCSS = function(url) { // 检查此文件是否已经被导入过 if (Import.isImported(url)) return; var head = document.getElementsByTagName("head")[0]; // IE6 cannot support appendchild for head when BASE tag is present. // So we have to use document.write as instead. // We need better solution for this IE bug. // var link = head.appendChild(document.createElement("link")); var link = document.createElement("link"); link.href = url; link.type = "text/css"; link.rel = "stylesheet"; if (document.readyState == "complete") { // if this method is called after the page loaded, for example, // in a script with defer tag, then use appendChild, // otherwise the document will be cleared when invoking // document.write. head.appendChild(link); } else { document.write(link.outerHTML); } }; Import.importJS = function(url, prefix) { // 检查此文件是否已经被导入过 if (Import.isImported(url)) return; // 通过AJAX获取文件内容 // alert(url); var script = Import.getScriptContent(url); // alert(script); // 加上命名空间并执行脚本 Import.execute(script, prefix); }; Import.execute = function(script, prefix) { if (prefix != null && prefix != "") { var variables = Import.analysScript(script); // 分析出脚本中所有的全局变量 if (variables.length > 0) { var pre = eval(prefix + " = {};"); // 根据prefix生成对象 for ( var i = 0; i < variables.length; i++) { var variable = variables[i]; // alert(variable); pre[variable] = null; } var extendScript = "; var pre=" + prefix + ";for(var attr in pre){try{pre[attr]=eval(attr);}catch(e){}}"; var wholeScript = "(function(){" + script + extendScript + "})();"; window.execScript(wholeScript); } } else { window.execScript(script); } }; Import.analysScript = function(script) { // 检查参数 if (script == null || script == "") return null; var globalVariables = null; // 定义词法状态机 var wordStateMachine = { currentState : "init", // 状态机的当前状态 wordCache : [], // 保存用来构造单词的缓存 stateObj : {}, // 保存状态间变量 getStateObj : function(state) { if (state && state != "") { if (this.stateObj[state] == null) this.stateObj[state] = {}; return this.stateObj[state]; } return null; }, process : function(script) { var self = this; var index = 0; var outputWords = []; while (index < script.length) { var c = script.charAt(index); var result = "self"; var word = self.wordCache.join(""); while (result == "self") { // 继续在当前字符上调用handler result = self.handlers[self.currentState](c); } if (result == "complete") { // 完成了一个单词的分析 // alert(word); var output = grammarStateMachine.process(word); if (output != null) { // alert("output:" + output); outputWords[outputWords.length] = output; } } else if (result == "next") { // 读取下一个字符 self.wordCache[self.wordCache.length] = c; index++; } } return outputWords; }, handlers : { "init" : function(char) { wordStateMachine.wordCache = []; if ("$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" .indexOf(char) >= 0) { // if(char == "$")alert(char); wordStateMachine.currentState = "identify_start"; } else if ("{}()".indexOf(char) >= 0) { wordStateMachine.currentState = "block_start"; return "self"; /* * } else if ("\"'".indexOf(char) >= 0) { // * 暂时取消字符串分析,因为不好处理正则表达式中的'和" wordStateMachine.currentState = * "quote_start"; * wordStateMachine.getStateObj("quote_start").quote = char; * return "next"; */ } else if (char == "/") { wordStateMachine.currentState = "comment"; return "next"; } return "next"; }, "identify_start" : function(char) { // 进入标识符分析 var result = "self"; if ("$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" .indexOf(char) >= 0) { result = "next"; } else if ("".indexOf(char) >= 0) { } else { wordStateMachine.currentState = "identify_finish"; result = "self"; } return result; }, "identify_finish" : function(char) { // 标识符分析完成 var result = "complete"; wordStateMachine.currentState = "init"; return result; }, "block_start" : function(char) { // 分析括号和代码块 wordStateMachine.currentState = "block_finish"; return "next"; }, "block_finish" : function(char) { wordStateMachine.currentState = "init"; return "complete"; }, "quote_start" : function(char) { // 分析引号 // alert(char + "," + wordStateMachine.wordCache.join("")); var finish = false; if (char == wordStateMachine.getStateObj("quote_start").quote) { for ( var i = wordStateMachine.wordCache.length - 1; i >= 0; i = i + 2) { var a = wordStateMachine.wordCache[i]; var b = wordStateMachine.wordCache[i - 1]; if (a != "\\") { finish = true; break; } else if (b != "\\") { finish = false; break; } } if (finish) { wordStateMachine.currentState = "quote_finish"; return "self"; } } return "next"; }, "quote_finish" : function(char) { alert(char + "," + wordStateMachine.wordCache.join("")); wordStateMachine.currentState = "init"; return "next"; }, "comment" : function(char) { // 分析注释 if (char == "/") { wordStateMachine.currentState = "comment_start"; wordStateMachine.getStateObj("comment").comment = "line"; } else if (char == "*") { wordStateMachine.currentState = "comment_start"; wordStateMachine.getStateObj("comment").comment = "block"; } else { wordStateMachine.currentState = "regex"; } return "self"; }, "comment_start" : function(char) { // alert(char+","+wordStateMachine.wordCache.join("")); if (wordStateMachine.getStateObj("comment").comment == "line" && char == "\n") { wordStateMachine.currentState = "comment_finish"; } else if (wordStateMachine.getStateObj("comment").comment == "block" && char == "/" && wordStateMachine.wordCache[wordStateMachine.wordCache.length - 1] != "\\") { wordStateMachine.currentState = "comment_finish"; } return "next"; }, "comment_finish" : function(char) { wordStateMachine.currentState = "init"; return "next"; }, "regex" : function(char) { // TODO: 需要实现表达式分析才能分析出正则表达式 wordStateMachine.currentState = "init"; return "next"; } } }; // 定义语义状态机 var grammarStateMachine = { currentState : "init", output : null, stateObj : {}, getStateObj : function(state) { if (state && state != "") { if (this.stateObj[state] == null) this.stateObj[state] = {}; return this.stateObj[state]; } return null; }, process : function(word) { var self = this; var result = "self"; var ret = null; while (result == "self") { result = self.handlers[self.currentState](word); } if (result == "next") { } else if (result == "complete") { ret = self.output; self.output = null; } return ret; }, handlers : { "init" : function(word) { // alert("init:"+word); if (word == "var") { grammarStateMachine.currentState = "variable_define"; } else if (word == "function") { grammarStateMachine.currentState = "function_define"; } else if (word == "{") { grammarStateMachine.currentState = "block"; grammarStateMachine.getStateObj("block").blockLevel = 0; return "self"; } return "next"; }, "block" : function(word) { var stateObj = grammarStateMachine.getStateObj("block"); if (word == "{") { stateObj.blockLevel++; } else if (word == "}") { stateObj.blockLevel--; if (stateObj.blockLevel == 0) { grammarStateMachine.currentState = "init"; } else if (stateObj.blockLevel < 0) { throw new Error("block unmatch"); } } return "next"; }, "variable_define" : function(word) { grammarStateMachine.output = word; grammarStateMachine.currentState = "variable_finish"; return "self"; }, "variable_finish" : function(word) { grammarStateMachine.currentState = "init"; return "complete"; }, "function_define" : function(word) { if (word == "(") { grammarStateMachine.currentState = "function_arg_block"; return "self"; } else { grammarStateMachine.output = word; grammarStateMachine.currentState = "function_arg_block"; } return "next"; }, "function_arg_block" : function(word) { if (word == "(") { } else if (word == ")") { grammarStateMachine.currentState = "function_search_body"; } return "next"; }, "function_search_body" : function(word) { if (word == "{") { grammarStateMachine.currentState = "function_start"; grammarStateMachine.getStateObj("function_start").blockLevel = 0; return "self"; } return "next"; }, "function_start" : function(word) { var stateObj = grammarStateMachine .getStateObj("function_start"); if (word == "{") { stateObj.blockLevel++; } else if (word == "}") { stateObj.blockLevel--; if (stateObj.blockLevel == 0) { grammarStateMachine.currentState = "function_finish"; return "self"; } } return "next"; }, "function_finish" : function(word) { // alert("function_finish:"+word) grammarStateMachine.currentState = "init"; return "complete"; } } }; // 进入自动状态机 globalVariables = wordStateMachine.process(script); return globalVariables; }; Import.getScriptContent = function(url) { var req = new ActiveXObject("Microsoft.XmlHttp"); var res; req.open("GET", url, false); req.send(); if (req.status != 404) { if (req.readystate == 4) { res = req.responseText; } } return res; }; Import.getFileType = function(url){ url = url.split("?")[0]; type = url.substring(url.length - 3); if(type.indexOf(".")==0){ return type; }else{ return ""; } } /** * 记录下导入的文件 */ Import.addImportingFile = function(url) { if (!Import.isImported(url)) { if(Import.getFileType(url) == ".js") Import.importingJSFiles.push(url); else Import.importingCSSFiles.push(url); } }; Import.addImportedFile = function(url) { if (!Import.isImported(url)) { if(Import.getFileType(url) == ".js"){ if(Import.importingJSFiles[Import.importingJSFiles.length - 1] == url){ Import.importingJSFiles.pop(); Import.importedJSFiles.push(url); } }else{ Import.importedCSSFiles.push(url); } } }; /** * 检查文件是否已经被导入过了 */ Import.isImported = function(url) { if(Import.getFileType(url) == ".js"){ for ( var i = 0; i < Import.importedJSFiles.length; i++) { if (Import.importedJSFiles[i] == url) { return true; } } } else { for ( var i = 0; i < Import.importedCSSFiles.length; i++) { if (Import.importedCSSFiles[i] == url) { return true; } } } return false; }; /** * 获取导入文件的完整URL,包括HTTP头 */ Import.getFullPathFromUrl = function(url) { var path = null; if (url.substr(0, 7).toLowerCase() == "http://") { // url为完整的URL地址 path = url; } else if (url.substr(0, 1) == "/") { // url以/开头,为以站点根目录开始的路径 path = "http://" + document.location.host + url; } else { var parentPage = document.location.href; var parentPath = parentPage.split("?")[0]; parentPath = parentPath.substring(0, parentPath.lastIndexOf("/") + 1); var currentScriptPath = Import.getCurrentScriptPath(); currentScriptPath = currentScriptPath.split("?")[0]; if (currentScriptPath.toLowerCase().indexOf("http://") == 0) { // 当前脚本路径是以http开头 path = currentScriptPath + url; } else { // 否则当前脚本路径为相对路径 // 查看是否有BASE标签 var base = document.getElementsByTagName("base")[0]; if (base) { var baseUrl = base.href; path = baseUrl + currentScriptPath + url; } else { path = parentPath + currentScriptPath + url; } } path = Import.toAbsolutePath(path); } return path; }; Import.toAbsolutePath = function(url) { // 转换为绝对URL var http = "http://"; if (url.toLowerCase().indexOf("http://") == 0) { url = url.substring(7, url.length); } var path = url.split("?")[0]; var queryString = (url.split("?").length > 1) ? "?" + url.split("?")[1] : ""; dt = path.split("/"); var newdt = []; for ( var i = 0; i < dt.length; i++) { var u = dt[i]; if (u == "..") { newdt.pop(); } else { newdt.push(u); } } return http + newdt.join("/") + queryString; }; /** * 获取当前运行的脚本文件的路径,路径不包括自身的文件名 * * @return */ Import.getCurrentScriptPath = function() { var js = Import.importingJSFiles; if (js && js.length > 0) { js = js[js.length - 1]; js = js.split("?")[0]; js = js.substring(0, js.lastIndexOf("/") + 1); } else { js = document.scripts; var src = js[js.length - 1].src; src = src.split("?")[0]; js = src.substring(0, src.lastIndexOf("/") + 1); } return js; }; /** * ImportFile类 * * @param path * @return */ Import.ImportFile = function(path) { this.path = path; this.fullPath = null; this.type = null; }; (function() { if (typeof $import == "undefined") { $import = Import.$import; } })(); </textarea> </p> <p class="right articalinfo"> 发表于 @ 2009年09月21日 18:10:00 | <a id="a_comment" href="#FeedBack" title="评论">评论( <span id="FeedbackCount_4577121">loading...</span> <script type="text/javascript"> AddFeedbackCountStack("4577121") </script> ) </a>| <span style="display: none;"><a class="a_edit" href="http://writeblog.csdn.net/PostEdit.aspx?entryId=4577121" title="编辑">编辑</a>|</span> <a href='mailto:webmaster@csdn.net?subject=Article%20Report!!!&body=Author:youyue%0D%0AURL:http://blog.csdn.net/ArticleContent.aspx?UserName=youyue&Entryid=4577121'> 举报</a>| <cite class="fav_csdnstylebykimi"><a href="JavaScript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();" class="fav_csdnstylebykimi" title="收藏到我的网摘中,并分享给我的朋友">收藏</a> </cite> </p> <span id="Post.ascx_ViewPost_PreviousAndNextEntriesDown"> <h3 class="pagego"> <a href="/youyue/archive/2009/09/21/4577014.aspx">旧一篇:用wmlscript实现MD5和BASE64加密</a> | <a href="/youyue/archive/2009/09/22/4580402.aspx">新一篇: JAVA中文字符编码问题详解</a></h3> </span> <div style="text-align: left;"> <!-- ca-pub-1076724771190722/blog_postpage_72890 --> <script type='text/javascript'> GA_googleFillSlot("blog_postpage_72890"); </script> </div> <div class="mutualitys"> <dl> <dt><span><a onclick="LogClickCount(this,215)" target="_blank" href="http://blog.csdn.net"> 查看最新精华文章 请访问博客首页</a></span>相关文章</dt> </dl> </div> </div> </div> <a name="FeedBack"></a> <script type="text/javascript"> var CurrentEntryId = '4577121'; var CurArticleTitle = 'Javascript中实现JS文件的导入+命名前缀'; var AllowComment = 'True'; var AllowAnonymousComment = /^true$/i.test('False'); </script> <div class="commentslist" id="commentslist"> </div> <script type="text/javascript" src="/js/CsdnDialog.js"></script> <script type="text/javascript"> function ChangeIdentifyingCode() { var url = $('#imgValidationCode').attr('src'); if (!(/&d=[\d\.]+$/).test(url)) url += "&d=1"; url = url.replace(/&d=[\d\.]+$/, "&d=" + Math.random()); $('#imgValidationCode').attr('src', url); } function OpenLoginDialog() { element = document.getElementById("loginBtn"); var position = absolutePoint(element); var dialogTop = position.y - 400; var dialogLeft = position.x - 220; var dialogWidth = 435; var dialogHeight = 420; showWindow({ url: 'http://passport.csdn.net/UserLogin.aspx?show=replyLogin&from=http%3a%2f%2fblog.csdn.net%2f!tools%2fLoginSussess.aspx' , title: '登录' , top: dialogTop , left: dialogLeft , width: dialogWidth , height: dialogHeight }); } function closeDialog(needRefresh) { closeWindow(); if (needRefresh) { var url = location.href; if ((/\?/g).test(url)) url = url.replace(/\?.*$/g, ("?" + Math.random()).replace(/\./g, "")); else url += ("?" + Math.random()).replace(/\./g, ""); location.href = url; } $("#SubmitFeedback").unbind("click"); $("#SubmitFeedback").bind("click", PostContent); } function absolutePoint(element) { var result = { x: element.offsetLeft, y: element.offsetTop }; element = element.offsetParent; while (element) { result.x += element.offsetLeft; result.y += element.offsetTop; element = element.offsetParent; } return result; } function startmarquee(lh, speed, delay, index) { var t; var p = false; var o = document.getElementById("marqueebox" + index); o.innerHTML += o.innerHTML; o.onmouseover = function () { p = true } o.onmouseout = function () { p = false } o.scrollTop = 0; function start() { t = setInterval(scrolling, speed); if (!p) o.scrollTop += 2; } function scrolling() { if (o.scrollTop % lh != 0) { o.scrollTop += 2; if (o.scrollTop >= o.scrollHeight / 2) o.scrollTop = 0; } else { clearInterval(t); setTimeout(start, delay); } } setTimeout(start, delay); } function addEventHandler(target, type, func) { if (target.addEventListener) target.addEventListener(type, func, false); else if (target.attachEvent) target.attachEvent("on" + type, func); else target["on" + type] = func; } addEventHandler(window, "load", function () { startmarquee(42, 50, 3000, 0); }); </script> <div class="commentnew"> <dl> <dt> <ul> <li class="left">发表评论</li> <script src="http://svc.csdn.net/ColumnService/RandomColumnContentJS.aspx?id=835ac618-5f1a-41b2-b4dc-716234f8d656&c=1&t=li" type="text/javascript"></script> </ul> </dt> <dd> <ul> <li class="lefttop">表 情:</li> <li class="right"><a href="#" onclick="return false;"> <img title="顶" alt="顶" class="brow" src="/images/emotions/e01.gif" /></a> <a href="#" onclick="return false;"> <img title="砸" alt="砸" class="brow" src="/images/emotions/e02.gif" /></a> <a href="#" onclick="return false;"> <img title="棒" alt="棒" class="brow" src="/images/emotions/e03.gif" /></a> <a href="#" onclick="return false;"> <img title="大笑" alt="大笑" class="brow" src="/images/emotions/e04.gif" /></a> <a href="#" onclick="return false;"> <img title="愤怒" alt="愤怒" class="brow" src="/images/emotions/e05.gif" /></a> <a href="#" onclick="return false;"> <img title="大哭" alt="大哭" class="brow" src="/images/emotions/e06.gif" /></a> <a href="#" onclick="return false;"> <img title="疑问" alt="疑问" class="brow" src="/images/emotions/e07.gif" /></a> <a href="#" onclick="return false;"> <img title="汗" alt="汗" class="brow" src="/images/emotions/e08.gif" /></a> <a href="#" onclick="return false;"> <img title="呕吐" alt="呕吐" class="brow" src="/images/emotions/e09.gif" /></a> <a href="#" onclick="return false;"> <img title="送花" alt="送花" class="brow" src="/images/emotions/e10.gif" /></a> </li> </ul> <ul> <li class="left">评论内容:</li> <li class="right"> <textarea id="content" class="textarea" onkeydown="if(event.ctrlKey && event.keyCode==13){return $('#SubmitFeedback').click();}"></textarea> </li> </ul> <div> <ul> <li class="left">用 户 名:</li> <li class="right"><span id="loginTips" class="right" style="display: none;"><a href="javascript:void(0);" onclick="OpenLoginDialog(this);return false;" class="red" id="loginBtn">登录</a> <a href="http://passport.csdn.net/CSDNUserRegister.aspx" target="_blank" class="red"> 注册</a> </span><span class="right" style="display: none;"> <input type="checkbox" id="anonymous" class="checkbox" />匿名评论 </span><span id="commentUser" class="left"></span></li> </ul> </div> <ul style="display: none;"> <li class="left">验 证 码:</li> <li class="right"> <input id="code" type="text" class="input" /> <a href="javascript:ChangeIdentifyingCode()"> <img id="imgValidationCode" alt="验证码" style="vertical-align: middle;" src="http://comments.blog.csdn.net/AntiBotImage.ashx?entryId=4577121" /></a> <a href="javascript:ChangeIdentifyingCode()">重新获得验证码</a> </li> </ul> <ul> <li class="left"> </li> <li class="right"> <input id="SubmitFeedback" type="button" value="发表评论" class="submitbtn" /> </li> </ul> </dd> <dd id="recommended" class="recruit"> <h5>热门招聘职位</h5> <ul id="marqueebox0"> <script src="http://ping.csdn.net/rsscache.aspx?rssurl=http://temp.csdn.net/Feed.aspx?Column=3550748a-ac9a-4ff1-ba62-3739fce143ba&count=12&area=226" type="text/javascript"></script> </ul> </dd> </dl> </div> <script type="text/javascript"> function addEventHandler(target, type, func) { if (target.addEventListener) target.addEventListener(type, func, false); else if (target.attachEvent) target.attachEvent("on" + type, func); else target["on" + type] = func; } addEventHandler(window, "load", function () { ({ anndelay: 5000, annst: 0, annstop: 0, annrowcount: 0, anncount: 0, annrows: [], annstatus: 0, announcementScroll: function () { var self = this; var annlis = self.annbody.getElementsByTagName("li"); if (self.annstop) { self.annst = setTimeout(function () { self.announcementScroll(); }, self.anndelay); return; } if (!self.annst) { var lasttop = -1; for (var i = 0; i < annlis.length; i++) { if (lasttop != annlis[i].offsetTop) { if (lasttop == -1) { lasttop = 0; } self.annrows[self.annrowcount] = annlis[i].offsetTop - lasttop; self.annrowcount++; } lasttop = annlis[i].offsetTop; } if (self.annrows.length == 1) { self.ann.onmouseover = self.ann.onmouseout = null; } else { self.annrows[self.annrowcount] = self.annrows[1]; self.annbodylis.innerHTML += self.annbodylis.innerHTML; self.annst = setTimeout(function () { self.announcementScroll(); }, self.anndelay); } self.annrowcount = 1; return; } if (self.annrowcount >= self.annrows.length) { self.annbody.scrollTop = 0; self.annrowcount = 1; self.annst = setTimeout(function () { self.announcementScroll(); }, self.anndelay); } else { self.anncount = 0; self.announcementScrollnext(self.annrows[self.annrowcount]); } }, announcementScrollnext: function (time) { var self = this; self.annbody.scrollTop++; self.anncount++; if (self.anncount != time) { self.annst = setTimeout(function () { self.announcementScrollnext(time); }, 10); } else { self.annrowcount++; self.annst = setTimeout(function () { self.announcementScroll(); }, self.anndelay); } }, play: function () { var self = this; self.annbody = document.getElementById('annbody'); if (!self.annbody) return; self.ann = document.getElementById('ann'); self.annbodylis = document.getElementById('annbodylis'); self.chal = document.getElementById('chal'); if (!self.annbodylis.getElementsByTagName("li").length) return; self.chal.style.display = ""; self.ann.onmouseover = function () { this.annstop = 1; }; self.ann.onmouseout = function () { this.annstop = 0; }; self.announcementScroll(); } }).play(); });?