1.按照CommonJS规范,在任何模块代码的作用域下内置了以下哪些变量?
A, module
B,context
C, require
D,exports
答:A,C,D可以参考:
阮一峰commjs文章:输出模块变量的最好方法是使用module.exports对象,加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的module.exports对象
var i = 1; var max = 30; module.exports = function () { for (i -= 1; i++ < max; ) { console.log(i); } max *= 1.1; };
使用require方法,加载example.js。 // main.js var example = require('./example.js');
2.以下关于application cache的说法,哪些是不正确的?
· A,对于目标页面而言,可以通过来启用application cache。
· B, 对于启用了application cache的页面,该页面默认不会被缓存。
· C,manifest文件仅在初次访问站点时才会被下载。//每次都会下载minifest
· D, 对于manifest中列出的资源文件,只要它们被修改,下次访问站点时就会被重新下载。//修改了不会重新下载
答:BCD(A没有写全)
解析:application cache是HTML5的一种新技术,应用缓存,HTML5 使用ApplicationCache 接口解决了由离线带来的部分难题。前提是你需要访问的web页面至少被在线访问过一次。
3.下面哪些技术可用于优化 CSS 图片加载 ?
· A CSSSprite
· B SVGSprite
· C,Iconfont
· D Base64
答:ABCD
4。程序员小马对某 Git 仓库执行一系列操作,请写出每个步骤对应的 Git 命令:
1. 从当前分支hotfix 切换到分支 feature
2. 添加新文件 feature.js
3. 提交文件 feature.js,日志消息为“添加新文件”
4. 将 feature 分支衍合(变基)到 master 分支(不考虑文件冲突)
5. 推送feature 分支到远程服务器 origin 的同名分支
git checkout feature
git add feature.js
git commit -m '添加新文件'
git rebase master
git push origin feature:feature
5.从前端工程师的角度如何提高页面的用户体验。
加载速度快
兼容各种浏览器
http://www.iteye.com/news/24291
6.
<divclass='mod-spm'data-spmid='123'>
<divclass='child_a'></div>
<divclass='child_b'></div>
<divclass='child_c'></div>
<divclass='child_d'></div>
</div>
<divclass='mod-spm'data-spmid='456'>
<divclass='child_a'></div>
<divclass='child_b'></div>
<divclass='child_c'></div>
<divclass='child_d'></div>
</div>
<divclass='mod-spm'data-spmid='789'>
<divclass='child_a'></div>
<divclass='child_b'></div>
<divclass='child_c'></div>
<divclass='child_d'></div>
</div>
有dom结构如上,请用原生代码(禁用jQuery作答)实现以下功能:
(a)计算鼠标在mod-spm区域内的停留时长,data-spm不同视为不同区域
(b)尽量减少性能损耗
(c)重复进入计时累加
(b)尽量减少性能损耗
(c)重复进入计时累加
7。有这样一个URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,请写一段JS程序提取URL中的各个GET参数(参数名和参数个数不确定),将其按key-value形式返回到一个json结构中,如{a:'1', b:'2', c:'', d:'xxx', e:undefined}。
function getQuery(url) { var query = url.split('?')[1]; if (!query) { return {}; } query = query.split('&'); var arr = {}; for (var i = 0, l = query.length; i < l; i++) { var temp = query[i].split('='); var key = decodeURIComponent(temp[0]);// var value = decodeURIComponent(temp[1] == null ? '' : temp[1]);//value可能是空 if (key in arr) { //这段if else是处理key重复 var valArr = arr[key]; if (typeof valArr === 'string') { valArr = [valArr]; } valArr.push(value); arr[key] = valArr; } else { arr[key] = value; } } return arr; }
8.简述浏览器中使用js跨域获取数据的几种方法
jsonp 加载script脚本来跨域
通过修改document.domain来跨子域
使用window.name来进行跨域
使用HTML5中新引进的window.postMessage方法来跨域传送数据
flash
9.如何配置让 nginx 对 js、html、css 文件进行 gzip 压缩输出?
10.请填写个人github地址
11.编写一个JavaScript函数,输入指定类型的选择器(仅需支持id,class,tagName三种简单CSS选择器,无需兼容组合选择器)可以返回匹配的DOM节点,需考虑浏览器兼容性和性能。
/*** @param selector {String} 传入的CSS选择器。* @return{Array}*/
var query = function(selector){
//返回查找到的节点数组return [];}
1 /** 2 * 用于表示标识符 3 * 4 * @type {string} 5 */ 6 var identifier = '(?:\\.|[\w-]|[^\x00-\xa0])+'; 7 8 /** 9 * 用于表示空白字符 10 * 11 * @type {string} 12 */ 13 var whitespace = '[\x20\t\r\n\f]'; 14 15 /** 16 * 基本选择器 17 * 18 * @type {Object} 19 */ 20 var expr = { 21 22 /** 23 * ID选择器 24 * 25 * @type {RegExp} 26 */ 27 'ID': new RegExp('^#(' + identifier + ')'), 28 29 /** 30 * 类选择器 31 * 32 * @type {RegExp} 33 */ 34 'CLASS': new RegExp('^\.(' + identifier + ')'), 35 36 /** 37 * 标签选择器 38 * 39 * @type {RegExp} 40 */ 41 'TAG': new RegExp('^(' + identifier + '|[*])') 42 }; 43 44 /** 45 * 用于匹配CSS属性转义字符 46 * 47 * @type {RegExp} 48 */ 49 var runescape = new RegExp('\\([\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig'); 50 51 /** 52 * 用于处理CSS属性转义字符的替换函数 53 * 54 * @param {*} _ 此参数仅占位 55 * @param {string} escaped 转义后的字符 56 * @param {string} escapedWhitespace 是否转义 57 * @return {*} 返回处理结果 58 */ 59 var funescape = function (_, escaped, escapedWhitespace) { 60 var high = '0x' + escaped - 0x10000; 61 62 // NaN表示不转义 63 if (isNaN(high) || escapedWhitespace) { 64 return escaped; 65 } 66 67 if (high < 0) { 68 return String.fromCharCode(high + 0x10000); 69 } 70 71 return String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00); 72 }; 73 74 75 /** 76 * 解码CSS属性转义字符 77 * 78 * @param {string} str 要解码的字符串 79 * @return {string} 解码后的字符串 80 */ 81 function unescape(str) { 82 return str.replace(runescape, funescape); 83 } 84 85 /** 86 * 对选择器进行词法分析 87 * 88 * @param {string} selector 选择器字符串 89 * @return {Array|null} 如果为空表示解析失败 90 */ 91 function tokenize(selector) { 92 93 var tokens = []; 94 95 while (selector) { 96 97 var matched = false; 98 99 // 处理基本选择器 100 for (var type in expr) { 101 102 var match; 103 if (expr.hasOwnProperty(type) && (match = expr[type].exec(selector))) { 104 105 matched = match.shift(); 106 107 tokens.push({ 108 matched: matched, 109 value: match, 110 type: type 111 }); 112 113 selector = selector.slice(matched.length); 114 } 115 } 116 117 if (!matched) { 118 break; 119 } 120 } 121 122 if (selector) { 123 throw new Error(selector + '解析失败'); 124 } 125 126 return tokens; 127 } 128 129 /** 130 * 进行兼容性检测 131 * 132 * @type {Object} 133 */ 134 var support = (function () { 135 136 var support = {}; 137 138 // 检查IE9以下不支持getElementsByClassName的问题 139 support.getByClass = !!document.getElementsByClassName; 140 141 // 检查IE67getElementById会返回Name的问题 142 var div = document.createElement('div'); 143 var expando = 'selector-' + new Date().getTime(); 144 document.body.appendChild(div).id = expando; 145 support.getById = !document.getElementsByName(expando).length; 146 147 // 释放多余的元素 148 document.body.removeChild(div); 149 div = null; 150 151 return support; 152 })(); 153 154 /** 155 * 用于生成过滤器的函数 156 * 157 * @type {Object} 158 */ 159 var filter = { 160 161 /** 162 * 类选择器 163 * 164 * @param {string} className 类名 165 * @return {Function} 过滤函数 166 */ 167 'CLASS': function (className) { 168 169 var pattern = new RegExp('(^|' + whitespace + ')' + className + '(' + whitespace + '|$)'); 170 171 return function (elem) { 172 return pattern.test(typeof elem.className === 'string' && elem.className || ''); 173 }; 174 }, 175 176 /** 177 * ID选择器 178 * 179 * @param {string} id 要匹配的ID 180 * @return {Function} 过滤函数 181 */ 182 'ID': support.getById ? function (id) { 183 184 var attrId = unescape(id); 185 186 return function (elem) { 187 return elem.getAttribute('id') === attrId; 188 }; 189 } : function (id) { 190 191 var attrId = unescape(id); 192 193 return function (elem) { 194 var node; 195 return (node = elem.getAttributeNode('id')) && node.value === attrId; 196 }; 197 }, 198 199 /** 200 * 标签选择器 201 * 202 * @param {string} nodeNameSelector 要过滤的标签名 203 * @return {Function} 过滤函数 204 */ 205 'TAG': function (nodeNameSelector) { 206 207 var nodeName = unescape(nodeNameSelector).toLowerCase(); 208 209 return nodeNameSelector === '*' ? function () { 210 return true; 211 } : function (elem) { 212 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 213 }; 214 } 215 216 }; 217 218 /** 219 * 将当前一个匹配数组打包成一个匹配函数 220 * 221 * @param {Array} matchers 匹配数组 222 * @return {Function} 匹配函数 223 */ 224 function elementMatcher(matchers) { 225 226 if (matchers.length > 1) { 227 228 return function (elem, context) { 229 var i = matchers.length; 230 while (i--) { 231 if (!matchers[i](elem, context)) { 232 return false; 233 } 234 } 235 return true; 236 }; 237 } 238 239 return matchers[0]; 240 } 241 242 /** 243 * 使用一组token生成一个匹配函数 244 * 245 * @param {Array} tokens 一组token 246 * @return {Function} 247 */ 248 function tokenMatcher(tokens) { 249 250 var matchers = []; 251 252 for (var i = 0, len = tokens.length; i < len; i++) { 253 matchers.push(filter[tokens[i].type].apply(null, tokens[i].value)); 254 } 255 256 return elementMatcher(matchers); 257 } 258 259 /** 260 * 合并两个数组或类数组到第一个数组 261 * 262 * @param {Array} target 数组或类数组 263 * @param {Array} args 数组或类数组 264 * @return {*} 返回first 265 */ 266 function merge(target, args) { 267 target = target || []; 268 269 var i = 1; 270 271 // 只传进来target时候直接返回target 272 if (arguments.length === i) { 273 return target; 274 } 275 276 var l = target.length; 277 278 for (; i < arguments.length; i++) { 279 args = arguments[i]; 280 281 if (args != null) { 282 var len = +args.length; 283 var j = 0; 284 285 while (j < len) { 286 target[l++] = args[j++]; 287 } 288 289 // 修复IE8下可能造成length失效的问题 290 if (isNaN(len)) { 291 while (args[j] !== undefined) { 292 target[l++] = args[j++]; 293 } 294 } 295 } 296 } 297 298 target.length = l; 299 300 return target; 301 302 } 303 304 /** 305 * 使用选择器找出相关的元素 306 * 307 * @param {string} selector 选择器字符串 308 * @param {HTMLElement|HTMLDocument} [context] 上下文对象 309 * @return {Array} 查询结果 310 */ 311 function query(selector, context) { 312 313 var results = []; 314 context = context || document; 315 316 if (!selector || typeof selector !== 'string') { 317 return results; 318 } 319 320 // 如果context不存在,表示查询非法 321 var nodeType; 322 if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) { 323 return results; 324 } 325 326 // 处理单标签的情况 327 var match; 328 if ((match = rquickExpr.exec(selector))) { 329 330 var m; 331 // 处理selector是ID的情况 332 if ((m = match[1])) { 333 var elem; 334 if (nodeType === 9) { 335 if ((elem = context.getElementById(m)) && elem.id === m) { 336 results.push(elem); 337 return results; 338 } 339 } 340 else { 341 if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) 342 && contains(context, elem) && elem.id === m) { 343 344 results.push(elem); 345 return results; 346 } 347 } 348 } 349 // 匹配selector是TAG的情况 350 else if (match[2]) { 351 return merge(results, context.getElementsByTagName(selector)); 352 } 353 // 匹配selector是CLASS的情况 354 else if ((m = match[3]) && support.getByClass) { 355 return merge(results, context.getElementsByClassName(m)); 356 } 357 } 358 359 var seed = []; 360 var found = false; 361 var tokens = tokenize(selector); 362 363 for (var i = 0, l = tokens.length; i < l && !found; i++) { 364 var token = tokens[i]; 365 if (support.getByClass && token.type === 'CLASS') { 366 merge(seed, context.getElementsByClassName(token.value[0])); 367 found = true; 368 } 369 else if (support.getById && token.type === 'ID' && context.nodeType === 9) { 370 var ele = document.getElementById(token.value[0]); 371 ele && seed.push(ele); 372 found = true; 373 } 374 else if (token.type === 'TAG') { 375 seed = context.getElementsByTagName(token.value[0]); 376 found = true; 377 } 378 } 379 380 !found && merge(seed, context.getElementsByTagName('*')); 381 382 if (!seed.length) { 383 return results; 384 } 385 386 var matcher = tokenMatcher(tokens); 387 388 for (var j = 0, len = seed.length; j !== len && (elem = seed[j]) != null; j++) { 389 if (elem && elem.nodeType === 1 && matcher(elem, context)) { 390 results.push(elem); 391 } 392 } 393 394 return results; 395 }