JavaScript简单的防抖函数
直接上代码:
function debounce(fn, time) { return function(args) { let that = this clearTimeout(fn.tid) fn.tid = setTimeout(() => { fn.call(that, args) }, time); } }
直接上代码:
function debounce(fn, time) { return function(args) { let that = this clearTimeout(fn.tid) fn.tid = setTimeout(() => { fn.call(that, args) }, time); } }
既然考虑的是那种极端的关键字搜索,通常的逐个遍历搜索显然是行不通的。如今用的是JavaScript,若不使用Hash表实在是太对不起这门语言了。有着对表特天独厚的支持,不妨就拿出少量的空间来换取大量的时间吧。
代码在下面:
var treeSearch = { makeTree: function(strKeys) { 'use strict'; var tblCur = {}, tblRoot, key, str_key, Length, j, i; tblRoot = tblCur; for (j = strKeys.length - 1; j >= 0; j -= 1) { str_key = strKeys[j]; Length = str_key.length; for (i = 0; i < Length; i += 1) { key = str_key.charAt(i); if (tblCur.hasOwnProperty(key)) { //生成子节点 tblCur = tblCur[key]; } else { tblCur = tblCur[key] = {}; } } tblCur.end = true; //最后一个关键字没有分割符 tblCur = tblRoot; } return tblRoot; }, search: function(content, tblRoot) { 'use strict'; var tblCur, p_star = 0, n = content.length, p_end, match, //是否找到匹配 match_key, match_str, arrMatch = [], //存储结果 arrLength = 0; //arrMatch的长度索引 while (p_star < n) { tblCur = tblRoot; //回溯至根部 p_end = p_star; match_str = ''; match = false; do { match_key = content.charAt(p_end); if (!(tblCur = tblCur[match_key])) { //本次匹配结束 p_star += 1; break; } else { match_str += match_key; } p_end += 1; if (tblCur.end === true) { //是否匹配到尾部 //找到匹配关键字 match = true; } } while (true); if (match === true) { //最大匹配 arrMatch[arrLength] = { //增强可读性 key: match_str, begin: p_star - 1, end: p_end }; arrLength += 1; p_star = p_end; } } return arrMatch; } };
测试代码:
function test(strContent, strKeys) { var arrMatch, tblRoot = treeSearch.makeTree(strKeys), t = new Date(); arrMatch = treeSearch.search(strContent, tblRoot); console.log('time is: ' + (new Date() - t) + 'mm'); console.log(arrMatch); } var s = (function() { var Things = [' ', '\n', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; var s = ''; for (var i = 1000000; i >= 0; i--) { s += Things[parseInt(Math.random() * Things.length) % Things.length]; } return s; })(); test(s, ['abc', 'efge', 'fun', 'tree']);
下面代码可以通过Ajax请求,直接向一个正常的文件上传接口提交请求,上传已经base64编码的图片文件。
直接贴代码:
function ajaxSubmitImageFile(base64Codes) { let convertBase64UrlToBlob = function(urlData) { let arr = urlData.split(','); let mime = arr[0].match(/:(.*?);/)[1]; let bytes = window.atob(urlData.split(',')[1]); // 去掉url的头,并转换为byte // 处理异常,将ascii码小于0的转换为大于0 let ab = new ArrayBuffer(bytes.length); let ia = new Uint8Array(ab); for (let i = 0; i < bytes.length; i++) { ia[i] = bytes.charCodeAt(i); } return new Blob([ab], { type: mime }); }; let getFileExt = function(urlData) { let arr = urlData.split(','); let mime = arr[0].match(/:(.*?);/)[1]; return mime.replace('image/', ''); }; let deferred = $.Deferred(); // let form = document.forms[0]; // var formData = new FormData(form); // 这里连带form里的其他参数也一起提交了,如果不需要提交其他参数可以直接FormData无参数的构造函数 let formData = new FormData(); let fileExt = getFileExt(base64Codes); // convertBase64UrlToBlob函数是将base64编码转换为Blob formData.append( 'upfile', convertBase64UrlToBlob(base64Codes), 'file_' + Date.parse(new Date()) + '.' + fileExt ); // append函数的第一个参数是后台获取数据的参数名,和html标签的input的name属性功能相同 // ajax 提交form $.ajax({ url: window.location.origin + '/article/ueditor/asp/controller.asp?action=uploadimage', type: 'POST', data: formData, // dataType: "text", processData: false, // 告诉jQuery不要去处理发送的数据 contentType: false, // 告诉jQuery不要去设置Content-Type请求头 success: function(data) { // console.log(data); if (data) { data = JSON.parse(data); if (data.state === 'SUCCESS') { deferred.resolve(window.location.origin + data.url); } else { deferred.reject('error'); } } else { deferred.reject('error'); } // window.location.href = "${ctx}" + data; }, xhr: function() { // 在jquery函数中直接使用ajax的XMLHttpRequest对象 let xhr = new XMLHttpRequest(); xhr.upload.addEventListener( 'progress', function(evt) { if (evt.lengthComputable) { let percentComplete = Math.round( (evt.loaded * 100) / evt.total ); window.console.log( '正在提交.' + percentComplete.toString() + '%' ); // 在控制台打印上传进度 } }, false ); return xhr; } }); return deferred.promise(); }
项目文件夹下建立 .prettierrc 文件,写入下面内容:
{ tabWidth: 4, singleQuote: true, // 用单引号 printWidth: 120, // 换行字符串阈值 semi: true, // 句末加分号 trailingComma: 'none', // 最后一个对象元素加逗号 bracketSpacing: true, // 对象,数组加空格 jsxBracketSameLine: false, // jsx > 是否另起一行 arrowParens: 'avoid', // (x) => {} 是否要有小括号 requirePragma: false, // 是否要注释来决定是否格式化代码 proseWrap: 'preserve' // 是否要换行 }
需要用到 style-loader 和 css-loader 两个包,首先安装它们(我直接安装在工程中):
npm i --save-dev style-loader css-loader
在你的 .ts 或 .tsx 源码中引入 CSS 样式表文件:
import './css/custom.css';
修改 webpack.config.js 配置文件,增加内容如下:
module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ], },
OK,执行打包命令:
webpack --mode production
?
在一些旧版浏览器中,你的 ES6 React 代码会报出如下错误:
Warning: React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills
比如,截图如下:
原因是因为 React 需要 ES6 中的 Map 和 Set 两种数据类型。
按照官方的方法,解决如下:
# npm i --save core-js
然后在你的代码中:
import 'core-js/es6/map'; import 'core-js/es6/set';
就 OK 啦 ?
下面附上官网上解决方法的截图
首先假定你的开发电脑上已经安装了npm。
全局安装TypeScript(安装tsc命令)
npm i -g typescript
全局安装Webpack(安装webpack命令)
npm i -g webpack
新建工程目录,并切换到工程目录下
mkdir ~/myProject# cd ~/myProject
初始化工程,并使用npm下载react和react-dom
npm init# npm i --save react react-dom @types/react @types/react-dom
初始化typescript环境,并创建tsc的配置文件tsconfig.json
tsc --init
修改tsconfig.json,增加或修改的内容
compilerOptions.target = "es6" compilerOptions.jsx = "react" compilerOptions.outDir = "path/to/js" compilerOptions.watch = true files = [ 'path/to/src/a.tsx', 'path/to/src/b.tsx' ]
创建webpack配置文件webpack.config.js,并填写内容
const path = require('path'); module.exports = { entry: { 'a': 'path/to/js/a.js', 'b': 'path/to/js/b.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, mode: 'development', // mode: 'production', };
实时监听文件变化,并自动打包
typescript实时编译
tsc --watch
因为之前的tsconfig.json配置文件中,配置了watch=true,所以默认加载当前目录的tsconfig.json时,会自动以监听的方式启动。一旦发现path/to/src目录下的tsx文件发生变化,会自动创建对应的path/to/js目录下的js文件。
webpack实时打包
webpack --watch
监听到path/to/js目录下的js文件内容发生变化,则自动进行打包操作,生成到dist目录下。
但是前面webpack.config.js文件中配置的mode模式为development开发模式。所以当项目最终上线时,还需要进行一次手动打包,直接指定模式为production生产模式。
生产模式会针对js和css内容进行压缩处理,去除其中的注释、空行等无用内容。
webpack --mode production
就这些了,暂时记录到这儿吧~~~
在使用NSB进行转发Ajax请求时,当出现跨域问题,可以在NSB的响应header中添加:
Access-Control-Allow-Origin: http://blog.ixcv.com
来实现接口的跨域请求。
设置为*则可以允许任意来源进行Ajax请求(当然,生产环境中没有这么玩儿的):
Access-Control-Allow-Origin: *
在使用AJAX时,如果遇到使用GBK或GB2312编码的页面,怎么办呢?首先需要把GBK编码的汉字转换成UTF8编码,才不会出现乱码的情况。
使用下面的函数进行编码:
function gb2utf8(data) { var glbEncode = []; gb2utf8_data = data; execScript("gb2utf8_data = MidB(gb2utf8_data, 1)", "VBScript"); var t=escape(gb2utf8_data).replace(/%u/g,"").replace(/(.{2})(.{2})/g,"%$2%$1").replace(/%([A-Z].)%(.{2})/g,"@$1$2"); t=t.split("@"); var i=0,j=t.length,k; while(++i < j) { k=t[i].substring(0,4); if(!glbEncode[k]) { gb2utf8_char = eval('0x' + k); execScript('gb2utf8_char = Chr(gb2utf8_char)', 'VBScript'); glbEncode[k]=escape(gb2utf8_char).substring(1,6); } t[i]=glbEncode[k]+t[i].substring(4); } gb2utf8_data = gb2utf8_char = null; return unescape(t.join('%')); }
代码如下:
$(function() { var lock = $('input[name="lock"]:checked').val(); alert(lock); });