canvas制作表情包
表情包的基础图片地址:
题目要求
加载表情包的基础图片到画布上,要求图片左上角坐标为 (50, 110),图片尺寸为 200 * 200在画布的 (20, 50)上绘制一个填充字体,字体内容为 "今天的我", 设置字体格式为 '30px arial'在画布的 (20, 90)上绘制一个填充字体,字体内容为 "还是一样的帅!", 设置字体格式为 '40px arial'代码:
//html //javascriptvar image = new Image();image.src = 'https://ke.qq.com/classroom/assets/lib/img/canvas-expression-base.png';//图片加载完成,则加载图片到画布上//需要注意的是,需要在图像加载完成后才能绘制图像到画布上,故需要监听图像 onload 事件,并在回调中绘制图像。image.onload = function() { context.drawImage(image, 50, 110, 200, 200);};// 增加文字context.font = '30px arial';context.fillText('今天的我', 20, 50);context.font = '40px arial';context.fillText('还是一样的帅!', 20, 90);
ul元素中添加100个li标签
在 h1 元素的后面新增一个 ul 元素,ul 元素中有一百个 li 元素,li 的内容就是 1-100 ,如下所示:
按要求新增元素
- 1
- 2
- 3 ......
- 98
- 99
- 100
禁止使用 innerHTML 属性!
代码:var body = document.body;var flagment = document.createDocumentFragment(); // 使用 fragment 来提高性能var ul = document.createElement('ul');body.appendChild(ul);for (var i=0; i < 100; i++) { var li = document.createElement('li'); var textNode = document.createTextNode(i + 1); li.appendChild(textNode); flagment.appendChild(li);}ul.appendChild(flagment);
将字符串转换为驼峰格式
css 中经常有类似 background-image 这种通过 - 连接的字符,通过 javascript 设置样式的时候需要将这种样式转换成 backgroundImage 驼峰格式,请完成此转换功能
- 以 - 为分隔符,将第二个起的非空单词首字母转为大写
- -webkit-border-image 转换后的结果为 webkitBorderImage
输入'font-size'
输出fontSize
function cssStyle2DomStyle(sName) { //字符串用空格分隔开 var arr = sName.split(''); //判断第一个字符是不是 '-',是的话就删除 if(arr.indexOf('-') == 0) arr.splice(0,1); //处理剩余的'-' for(var i=0; i
代码二:
//去除参数字符串的中划线连接符,在这里使用到字符串分割方法 split//获取去除中划线连接符的单词数组,并保存在一个新的变量 strArr//需要判断该数组第一项是否为空,如果为空则去掉。如 '-a-b-c'.split('-'); // 返回的是 ['', a, b, c] 第一项便为空字符串//使用循环语句,设置起始坐标 i = 1 即只从第二个单词开始来进行处理//将每个单词的首字母调用字符串大写方法 toUpperCase//将更改的首字母字符和单词后面的字符再次拼接起来,成为一个新的单词字符串//循环后将单词数组拼接成一个完整的字符串,使用了数组的方法 joinfunction convertToCamelCase(str) { // 去除中划线分隔符获取单词数组 var strArr = str.split('-'); // 如果第一个为空,则去掉 if(strArr[0] === '') { strArr.shift(); } // 定义返回结果 result var result; // 遍历第二个单词到最后一个单词,并转换单词首字母为答谢 for(var i = 1, len = strArr.length; i < len; i++){ strArr[i] = strArr[i][0].toUpperCase() + strArr[i].substring(1); } return strArr.join('');}如果了解正则表达式的同学可以这样写:function convertToCamelCase(str) { return str.replace(/\-[a-z]/g , function(a, b){ return b == 0 ? a.replace('-','') : a.replace('-','').toUpperCase(); });}
颜色字符串转换
将 rgb 颜色字符串转换为十六进制的形式,如 rgb(255, 255, 255) 转为 #ffffff
- rgb 中每个 , 后面的空格数量不固定
- 十六进制表达式使用六位小写字母
- 如果输入不符合 rgb 格式,返回原始输入示例1
输入
'rgb(255, 255, 255)'
输出
#ffffff
代码:
/* 10 11 12 13 14 15 0123456789 a b c d e f 12345678910 11 12 13 14 15 16 16进制: 十位数 = rgb数/16 个位数 = rgb数/16的余数*/function rgb2hex(sRGB) { return sRGB.replace(/^rgb\((\d+)\s*\,\s*(\d+)\s*\,\s*(\d+)\)$/g, function(a, r, g, b){ return '#' + hex(r) + hex(g) + hex(b); }); }function hex(n){ return n < 16 ? '0' + (+n).toString(16) : (+n).toString(16);}
求二次方
为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组
输入[1, 2, 3, 4]
输出
[1, 4, 9, 16]
代码:
function square(arr) { var newArr=[]; arr.forEach(function(e){ //遍历原数组,并同时求平方,加入新数组 newArr.push(e*e); }); return newArr;}
避免全局变量
给定的 js 代码中存在全局变量,请修复:
function globals() { myObject = { name : 'Jory' }; return myObject;}
思路:在Javascript语言中,声明变量使用的都是关键字var,如果不使用var而直接声明变量,则该变量为全局变量。
function globals() { //只需要在声明myObject时加上var就行了 var myObject = { name : 'Jory' }; return myObject;
正确的使用 parseInt
修改 js 代码中 parseInt 的调用方式,使之通过全部测试用例
示例1输入'12'
输出
12
示例2
输入'12px'
输出
12
示例3
输入'0x12'
输出
0
代码:
function parse2Int(num){ return parseInt(num,10);}
计时器
实现一个打点计时器,要求:
1.从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 12.返回的对象中需要包含一个 cancel 方法,用于停止定时操作3.第一个数需要立即输出思路:setInterval() 方法会按照指定周期不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。注意第一个数需要立即输出即可。function count(start, end) { //立即输出第一个值 console.log(start++); var timer = setInterval(function(){ if(start <= end){ console.log(start++); }else{ clearInterval(timer); } },100); //返回一个对象 return { cancel : function(){ clearInterval(timer); } }; }
函数的上下文
题目描述:将函数 fn 的执行上下文改为 obj 对象
示例1输入function () {return this.greeting + ', ' + this.name + '!!!';}, {greeting: 'Hello', name: 'Rebecca'}
输出
Hello, Rebecca!!!
代码:
function speak(fn, obj) { return fn.call(obj);}
流程控制
题目描述:
实现 fizzBuzz 函数,参数 num 与返回值的关系如下:1、如果 num 能同时被 3 和 5 整除,返回字符串 fizzbuzz2、如果 num 能被 3 整除,返回字符串 fizz3、如果 num 能被 5 整除,返回字符串 buzz4、如果参数为空或者不是 Number 类型,返回 false5、其余情况,返回参数 num示例1输入15
输出
fizzbuzz
代码:
function fizzBuzz(num) { if(isNaN(num)){ return false; } var str=''; if(num%3===0){ str+='fizz'; }; if(num%5===0){ str+='buzz'; } return str||num;}
返回函数
题目描述:
实现函数 functionFunction,调用之后满足如下条件:1、返回值为一个函数 f2、调用返回的函数 f,返回值为按照调用顺序的参数拼接,拼接字符为英文逗号加一个空格,即 ', '3、所有函数的参数数量为 1,且均为 String 类型示例1输入functionFunction('Hello')('world')
输出
Hello, world
代码:
function functionFunction (arg1) { return function(arg2){ return arg1 + ', ' + arg2; };}
二次封装函数
已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:
1、返回一个函数 result,该函数接受一个参数2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致// 一般写法function partial(fn, str1, str2) { function result(str3) { return fn(str1, str2, str3); } return result;} // callfunction partial(fn, str1, str2) { function result(str3) { return fn.call(this, str1, str2, str3); } return result;} // apply(这里只是为了对照)function partial(fn, str1, str2) { function result(str3) { return fn.apply(this, [str1, str2, str3]); } return result;} // 这个bind会生成一个新函数对象, 它的str1, str2参数都定死了, str3未传入, 一旦传入就会执行function partial(fn, str1, str2) { return fn.bind(this, str1, str2); // 或 return fn.bind(null, str1, str2);} // bind同上, 多了一步, 把str3传入的过程写在另一个函数里面, 而另一个函数也有str1, str2参数function partial(fn, str1, str2) { function result(str3) { return fn.bind(this, str1, str2)(str3); } return result;} // 匿名函数function partial(fn, str1, str2) { return function(str3) { return fn(str1, str2, str3); }}// ES6const partial = (fn, str1, str2) => str3 => fn(str1, str2, str3);
使用 arguments
函数 useArguments 可以接收 1 个及以上的参数。请实现函数 useArguments,返回所有调用参数相加后的结果。本题的测试参数全部为 Number 类型,不需考虑参数转换。
输入
1, 2, 3, 4
输出
10
思路:
本题考查的是对于arguments的使用,arguments能获得函数对象传入的参数组,类似与一个数组,能够通过length获取参数个数,能通过下标获取该位置的参数,但是它不能使用forEach等方法。本题先通过arguments.length获得参数个数,然后循环求和,得出结果。
代码
function useArguments() { /* 因为参数数量不定,可以先获取参数个数arguments.length 然后循环求值 */ //声明一个变量保存最终结果 var sum = 0; //循环求值 for(var i = 0; i < arguments.length; i++){ sum += arguments[i]; } return sum; }
二次封装函数
实现函数 partialUsingArguments,调用之后满足如下条件:
1、返回一个函数 result2、调用 result 之后,返回的结果与调用函数 fn 的结果一致3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数思路:
arguments不能用slice方法直接截取,需要先转换为数组,var args = Array.prototype.slice.call(arguments);合并参数可以使用concat方法,并且也需要将arguments先转换为数组才能使用concat进行合并。最用使用apply执行传入的函数即可。代码
function partialUsingArguments(fn) { //先获取p函数第一个参数之后的全部参数 var args = Array.prototype.slice.call(arguments,1); //声明result函数 var result = function(){ //使用concat合并两个或多个数组中的元素 return fn.apply(null, args.concat([].slice.call(arguments))); } return result; }
柯里化
题目描述
已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件:1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数)2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 13、调用 b 之后,返回一个函数 c, c 的 length 属性值为 14、调用 c 之后,返回的结果与调用 fn 的返回值一致5、fn 的参数依次为函数 a, b, c 的调用参数示例1输入var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3);
输出
6
代码
function curryIt(fn) { //获取fn参数的数量 var n = fn.length; //声明一个数组args var args = []; //返回一个匿名函数 return function(arg){ //将curryIt后面括号中的参数放入数组 args.push(arg); //如果args中的参数个数小于fn函数的参数个数, //则执行arguments.callee(其作用是引用当前正在执行的函数,这里是返回的当前匿名函数)。 //否则,返回fn的调用结果 if(args.length < n){ return arguments.callee; }else{ return fn.apply("",args); } } }
且运算
题目描述
返回参数 a 和 b 的逻辑且运算结果示例1输入false, true
输出
false
代码
function and(a, b) { return a&&b;}
二进制转换
题目描述
给定二进制字符串,将其换算成对应的十进制数字示例1输入'11000000'
输出
192
代码
function base10(str) { return parseInt(str,2);}
其它进制转十进制
/** 其它进制转十进制 parseInt(str,2) parseInt(str,8) parseInt(str,16) */
[parseInt()函数](
改变上下文
将函数 fn 的执行上下文改为 obj,返回 fn 执行后的值
输入
alterContext(function() {return this.greeting + ', ' + this.name + '!'; }, {name: 'Rebecca', greeting: 'Yo' })
输出
Yo, Rebecca!
代码
在JavaScript中,函数是一种对象,其上下文是可以变化的,对应的,函数内的this也是可以变化的,函数可以作为一个对象的方法,也可以同时作为另一个对象的方法,可以通过Function对象中的call或者apply方法来修改函数的上下文,函数中的this指针将被替换为call或者apply的第一个参数。将函数 fn 的执行上下文改为 obj 对象,只需要将obj作为call或者apply的第一个参数传入即可。function alterContext(fn, obj) {return fn.call(obj);}function alterContext(fn, obj) {return fn.apply(obj);}
判断是否包含数字
给定字符串 str,检查其是否包含数字,包含返回 true,否则返回 false
输入
'abc123'
输出
true
代码
方法一//判断字符串中是否含有数字,可以用正则表达式。/\d/可以匹配字符串中的数字字符,用test方法可以检测。function containsNumber(str) {var b = /\d/;return b.test(str);}方法二function containsNumber(str) { var arr = str.split(''); //切割为数组 for (var i = 0; i < arr.length; i++) { //遍历数组 if (!isNaN(parseInt(arr[i]))) { //判断是否为数字 return true; break; //一旦有数字跳出循环 } } return false;} //else 里面写 return false 第一个字符如果不是数字,就会返回false ,然后就终止了方法三function containsNumber(str) { for(var i=0;i<10;i++){ if(str.indexOf(i)!=-1){ return true; } } return false;}
属性遍历
找出对象 obj 不在原型链上的属性(注意这题测试例子的冒号后面也有一个空格~)
1、返回数组,格式为 key: value2、结果数组不要求顺序输入
var C = function() {this.foo = 'bar'; this.baz = 'bim';}; C.prototype.bop = 'bip'; iterate(new C());
输出
["foo: bar", "baz: bim"]
代码
方法一可以使用for-in来遍历对象中的属性,hasOwnproperty方法能返回一个布尔值,指出一个对象是否具有指定名称的属性。此方法无法检查该对象的原型链中是否具有该属性,该属性必须为对象本身的属性。 function iterate(obj) { var arr = []; //使用for-in遍历对象属性 for(var key in obj){ //判断key是否为对象本身的属性 if(obj.hasOwnProperty(key)){ //将属性和值按格式存入数组 arr.push(key+": "+obj[key]); } } return arr; }方法二function iterate(obj) { return Object.getOwnPropertyNames(obj).map(function(key){ return key+": "+obj[key]; });}
检查重复字符串
给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回 true,否则返回 false
输入
'rattler'
输出
true
代码
//方法一function containsRepeatingLetter(str) { var reg=/[a-zA-Z]/; for(var i=0,len=str.length;i
获取指定字符串
给定字符串 str,检查其是否包含 连续3个数字
1、如果包含,返回最新出现的 3 个数字的字符串2、如果不包含,返回 false输入
'9876543'
输出
987
代码
//连续3个数用正则表达式是/\d{3}/function captureThreeNumbers(str) {//声明一个数组保存匹配的字符串结果 var reg;//如果arr存在目标结果,则返回第一个元素,即最早出现的目标结果 if(reg = str.match(/\d{3}/)){ return reg[0]; }else{ return false; }}
该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。
判断是否符合指定格式
给定字符串 str,检查其是否符合如下格式
1、XXX-XXX-XXXX2、其中 X 为 Number 类型示例1输入'800-555-1212'
输出
true
代码
function matchesPattern(str) { return (/^\d{3}\-\d{3}\-\d{4}$/).test(str);}