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.jsvar 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 featuregit add feature.jsgit commit -m '添加新文件'git rebase mastergit push origin feature:feature
5.从前端工程师的角度如何提高页面的用户体验。
加载速度快
兼容各种浏览器
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)重复进入计时累加
7。有这样一个URL:,请写一段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: type111 });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 要匹配的ID180 * @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 一组token246 * @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 {*} 返回first265 */266 function merge(target, args) {267 target = target || [];268 269 var i = 1;270 271 // 只传进来target时候直接返回target272 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 }