1.关于购物的一道题,题目很简单:最近不是双十一吗,小美想要尽可能多的买各种商品,但小美只有一定数额的钱,规定每件商品只能买一件,问最后小美花了多少钱?
用例:
- 输入购买上限mPrice:188
- 输入一串以空格分隔的字符串,代表不同的商品的价格pStr:50 42 9 15 105 63 14 30
- 输出:160
注:mPrice最大不超过一万。
解:
// 获取应买物品的总价格
function getRes(mPrice, pStr) {
var arr = sortPrice(pStr.split(' '));
var price = 0;
for (var i in arr) {
var tempPrice = price + parseInt(arr[i]);
if (tempPrice <= mPrice) price = tempPrice;
else return price;
}
}
console.log(getRes(188, '50 42 9 15 105 63 14 30'));
// 对所有的物品价格排序
function sortPrice(arr) {
// 桶排序,内存溢出(失败)
// var temp = new Array(10000);
// for (var i in temp) {
// temp[i] = 0;
// }
// for (var i in arr) {
// temp[arr[i]]++;
// }
// var res = [];
// for (var i = 0; i < 10000; i++) {
// while (temp[i] != 0) {
// res.push(i);
// temp[i]--;
// }
// }
// return res;
// 冒泡排序
// var len = arr.length;
// for (var i = 0; i < len - 1; i++) {
// for (var j = 0; j < len - 1 - i; j++) {
// // console.log(parseInt(arr[j]));
// if (parseInt(arr[j]) > parseInt(arr[j + 1])) {
// // console.log(111);
// var temp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = temp;
// }
// }
// }
// return arr;
// 通过Object.keys来排序
var obj = {};
for (var i in arr) {
obj[arr[i]] = '';
}
return Object.keys(obj);
}
因为给出的上限范围为10000,一开始就想着通过桶排序的思想来做,但是运行时发现出错,报错说JavaScript heap out of memory,也就是内存溢出。接着想到的就是冒泡排序来做,当然其他的排序算法都行,最后想到了一个方法,通过Object.keys()可以针对对象属性均为数字字符串进行数字的排序原理,可以实现简便的语句。思路就不用说什么了吧。
2.给一个输入框、一个按钮,输入框中填写一个数字n,点击按钮生成一个n*n的表格,并且要求实现以下的效果:
- 鼠标虚浮在一个格子上,格子颜色变红,移开恢复(默认颜色为白色);
- 点击格子,格子颜色变蓝,而且鼠标hover也没什么变化,再次点击,恢复上面的状态;
思路:
- 通过字符串拼接的方式动态生成表格,并将其渲染出来;
- 通过hover进行hover效果;
- 通过在点击格子时为格子添加一个class,并设置样式为background-color: blue !important;来使得格子变蓝的同时不再受hover的影响;
- 通过事件代理的原理来绑定click事件减少dom操作;
解:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
.box-item {
width: 50px;
height: 50px;
box-sizing: border-box;
display: inline-block;
border: 1px solid #000;
vertical-align: top;
}
.box-item:hover {
background-color: red;
}
.blue {
background-color: blue !important;
}
</style>
</head>
<body>
<section>
<div class="edit-box">
<input class="num" type="number" value="0" />
<button class="init-button">初始化盒子</button>
</div>
<div class="grid-box">
<!-- <span class="box-item"></span> -->
</div>
</section>
</body>
<script>
var num = document.getElementsByClassName('num')[0];
var btn = document.getElementsByClassName('init-button')[0];
var gridBox = document.getElementsByClassName('grid-box')[0];
btn.onclick = function () {
n = num.value;
var gridStr = '';
for (var i = 0; i < n * n; i++) {
gridStr += '<span class="box-item"></span>';
}
gridBox.style.width = (n * 50) + 'px';
gridBox.style.height = (n * 50) + 'px';
gridBox.innerHTML = gridStr;
// click点击颜色切换设置
var flagArr = new Array(n * n);
for (var i = 0; i < n * n; i++) flagArr[i] = false;
var boxItems = Array.prototype.slice.call(document.getElementsByClassName('box-item'));
gridBox.onclick = function (e) {
console.log(flagArr[0]);
var target = e.target || e.srcElement;
var index = boxItems.indexOf(target);
if (index != -1) {
if (!flagArr[index]) {
target.className += ' blue';
} else {
removeCla(target, 'blue');
}
flagArr[index] = !flagArr[index];
}
}
}
// 辅助函数
function removeCla(el, claName) {
var cla = el.className;
var arr = cla.split(' ');
var index = arr.indexOf(claName);
if (index != -1) {
arr.splice(index, 1);
el.className = arr.join(' ');
}
}
</script>
</html>
上面的class的操作其实是可以用classlist来进行相应的操作,不过其兼容性会相对差一些。
3.一道页面效果的编写题(写了我将近一天。。。再加上一些优化调试。。。),下面给出题目:
请根据提供的psd文件,完成一个静态(HTML)页面的设计,预览如下。
要求:
- 1. 尽可能按照设计稿样式实现(文字字体除外);
- 2. 页面应该设计为占满浏览器宽度;
- 3. 请实现图片轮播效果(可用多张重复图片);
- 4. 提交HTML文件,便于我们检验。
这道题的代码码我放到我github上一个轮播器总结的demo中:
4. 已知一个思维导图如下:
该思维导图对应的数据如下:
奴隶社会,非洲,古埃及文明,金字塔
,亚洲,两河流域文明,汉谟拉比法典
,,古印度,种姓制度
,,,佛教的创立
,欧洲,希腊,希腊城邦
,,,雅典民主
,,罗马,城邦
,,,帝国的征服与扩展
,,希腊罗马古典文化,建筑艺术
,,,公历
备注:声明一个 String 变量存储使用即可。
将上述字符串数据按照如下规则转换成与思维导图结构相同的json。
奴隶社会,非洲
,亚洲
,,古印度
,欧洲
转换成的json如下:
{
"奴隶社会": [
{
"非洲": []
},
{
"亚洲": [
{
"古印度": []
}
]
},
{
"欧洲": []
}
]
}
请实现如下 JavaScript 函数:
function str2json(str) {
code //你的实现代码
}
题目已经讲的很清楚了,就是将上面格式的数据解析为上面形式的json数据,换言之,解这道题的关键是要弄懂它的一个解析规则。
其实还是很简单的,如下:
代码如下,通过递归的方法解决:
// 由于是在windows下编写,用\r\n作为换行分隔符
var s = "奴隶社会,非洲,古埃及文明,金字塔\r\n,亚洲,两河流域文明,汉谟拉比法典\r\n,,古印度,种姓制度\r\n,,,佛教的创立\r\n,欧洲,希腊,希腊城邦\r\n,,,雅典民主\r\n,,罗马,城邦\r\n,,,帝国的征服与扩展\r\n,,希腊罗马古典文化,建筑艺术\r\n,,,公历";
// main函数
function str2json (str) {
// 获取每一条规则
var arr = str.split('\r\n');
return JSON.stringify(parse(arr));
}
// 输出解析json字符串
console.log(str2json(s));
/* 辅助方法 */
// 获取s头部,的数量
function getPreNum (s) {
var reg = /^,*/;
return reg.exec(s)[0].length;
}
// 删除每一条规则第一个,号
function delPreTag (arr) {
var len = arr.length;
for (var i in arr) {
arr[i] = arr[i].substring(1);
}
}
// 执行解析操作
function parse (arr) {
// 用于记录第二层级数据项(根下一项)的起始位置
var indexArr = [];
// 输出结果obj
var obj = {};
// 1. 首先先将根属性取出
// 如果数组为空,直接返回一个空的数组
if (arr.length === 0) return obj;
// 如果数组中仅包含一项,并且没有','标识,则直接返回该字段
if (arr.length === 1 && arr[0].indexOf(',') === -1) {
return arr[0];
}
var index = arr[0].indexOf(',');
var root = arr[0].substring(0, index);
obj[root] = [];
arr[0] = arr[0].substring(index);
// 2. 获取第二层级数据项(根下一层数据)的起始下标
for (var i = 0; i < arr.length; i++) {
// 如果头部,数量为1
if (getPreNum(arr[i]) === 1) {
indexArr.push(i);
}
}
// 临时的一个数组,用于存放每个二级分组
var tempArr = [];
// 3. 将每条规则的第一个,号删除
delPreTag(arr);
// 4. 将每一个二级分组提取到tempArr中
for (var i = 0; i < indexArr.length; i++) {
if (i !== indexArr.length - 1) {
tempArr.push(arr.slice(indexArr[i], indexArr[i + 1]));
} else {
tempArr.push(arr.slice(indexArr[i]));
}
}
// 5. 对tempArr进行遍历回调
for (var i in tempArr) {
obj[root].push(parse(tempArr[i]));
}
return obj;
}
5. 关于js中的变量重复声明问题
对于es5,对同一个变量声明两次,不会报错,后声明的会值会覆盖先声明的;
对于es6,比如说同一个变量声明两次,会报错SyntaxError: Identifier 'xxx' has already been declared
6. display有哪些值
这里就不一一研究,之后单独总结一下。
提一下display: block、inline-block、inline这两者的区别有哪些?
- block设置的元素前后有换行,并且可以设置宽高;
- inline设置的元素前后没有换行,不可以设置宽高;
- inline-block设置的元素前后没有换行,可以设置宽高;
另外,简单说说inline-block的baseline问题,看几张图就知道了:
。。。
以下单独总结
。。。
7. 事件绑定的方法
8. 事件循环机制