首页
统计
墙纸
留言
Search
1
PVE8优化
19 阅读
2
mysql创建数据库
12 阅读
3
jenkins根据分支、文件夹打包
12 阅读
4
vue-cli注册全局方法
7 阅读
5
开心的加班
7 阅读
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
登录
/
注册
Search
标签搜索
vue+elementui
Cicaba
累计撰写
146
篇文章
累计收到
13
条评论
首页
栏目
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
页面
统计
墙纸
留言
搜索到
25
篇与
的结果
2018-07-12
webpack按需加载
**require.ensurerequire.ensure() 是 webpack 特有的,已经被 import() 取代**require.ensure(dependencies: String[], callback: function(require), errorCallback: function(error), chunkName: String) //示例 const home = (location, callback) => { require.ensure([], require => { callback(null, require('./HomePage.jsx')) }, 'home') }给定 dependencies 参数,将其对应的文件拆分到一个单独的 bundle 中,此 bundle 会被异步加载。当使用 CommonJS 模块语法时,这是动态加载依赖的唯一方法。意味着,可以在模块执行时才运行代码,只有在满足某些条件时才加载依赖项。dependencies:字符串构成的数组,声明 callback 回调函数中所需的所有模块。callback:只要加载好全部依赖,webpack 就会执行此函数。require 函数的实现,作为参数传入此函数。当程序运行需要依赖时,可以使用 require() 来加载依赖。函数体可以使用此参数,来进一步执行 require() 模块。errorCallback:当 webpack 加载依赖失败时,会执行此函数。chunkName:由 require.ensure() 创建出的 chunk 的名字。通过将同一个 chunkName 传递给不同的 require.ensure() 调用,我们可以将它们的代码合并到一个单独的 chunk 中,从而只产生一个浏览器必须加载的 bundle。
2018年07月12日
2 阅读
0 评论
0 点赞
2018-07-11
js技巧
获取Element所在的索引, Array.prototype.indexOf.call(ElementCollection,targetElement)获取字符串中某个字符存在个数. String.split('targetString').length-1
2018年07月11日
3 阅读
0 评论
0 点赞
2018-06-28
js获取设置光标位置
window.getSelection() //返回一个 Selection 对象,表示用户选择的文本范围或光标的当前位置。 <!DOCTYPE html> <html> <head> <title>js24.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> <!-- 输入完毕之后光标自动移动到下一个框的方法 --> <script type="text/javascript"> function moveNext(object, index) { if (object.value.length == 4) { document.forms[0].elements[index + 1].focus(); } } function showResult() { var f = document.forms[0]; var result = ""; for (var i = 0; i < 4; i++) { result += f.elements[i].value; } alert(result); } </script> </head> <body onload="document.forms[0].elements[0].focus();"> <form> <input type="text" size=3 maxlength=4 onkeyup="moveNext(this,0);">- <input type="text" size=3 maxlength=4 onkeyup="moveNext(this,1);">- <input type="text" size=3 maxlength=4 onkeyup="moveNext(this,2);">- <input type="text" size=3 maxlength=4 onkeyup="moveNext(this,3);"><br> <input type="button" value="显示所有" onclick="showResult();"> </form> </body>
2018年06月28日
1 阅读
0 评论
0 点赞
2018-06-28
判断360浏览器
window.onload = function() { //application/vnd.chromium.remoting-viewer 可能为360特有 var is360 = _mime("type", "application/vnd.chromium.remoting-viewer"); if (isChrome() && is360) { alert("检测到是360浏览器"); } } //检测是否是谷歌内核(可排除360及谷歌以外的浏览器) function isChrome() { var ua = navigator.userAgent.toLowerCase(); return ua.indexOf("chrome") > 1; } //测试mime function _mime(option, value) { var mimeTypes = navigator.mimeTypes; for (var mt in mimeTypes) { if (mimeTypes[mt][option] == value) { return true; } } return false; }
2018年06月28日
1 阅读
0 评论
0 点赞
2017-12-29
XML的解析new DOMParser.parseFromString()
解析 XML 标记来创建一个文档。构造函数new DOMParser()说明DOMParser 对象解析 XML 文本并返回一个 XML Document 对象。要使用 DOMParser,使用不带参数的构造函数来实例化它,然后调用其 parseFromString() 方法:var doc = (new DOMParser()).parseFromString(text)IE 不支持 DOMParser 对象。相反,它支持使用 Document.loadXML() 的 XML 解析。注意,XMLHttpRequest 对象也可以解析 XML 文档。参阅 XMLHttpRequest 的 responseXML 属性。DOMParser.parseFromString()解析 XML 标记语法parseFromString(text, contentType)text 参数是要解析的 XML 标记。contentType 是文本的内容类型。可能是 "text/xml" 、"application/xml" 或 "application/xhtml+xml" 中的一个。注意,不支持 "text/html"。返回值保存 text 解析后表示的一个 Document 对象。参阅 Document.loadXML(),了解这个方法的一个特定于 IE 的替代
2017年12月29日
2 阅读
0 评论
0 点赞
2017-12-28
牛逼的Object.defineProperty
var obj = { name: '小米'}; Object.defineProperty(obj, "age", { value:18, //属性值 writable:true,//是否可写 enumerable: true,//该属性是否可以枚举 configurable: true,//属性的总开关(如果是false,下次设置将无效) }); Object.defineProperty(obj,"age",{ //get set 方法不能同时和 value writable 存在 get(){ return 22 //必须返回一个 }, set(val){ console.log(val) } }) obj.age=24
2017年12月28日
1 阅读
0 评论
0 点赞
2017-11-26
JS获取各种宽高
IE中: document.body.clientWidth ==> BODY对象宽度 document.body.clientHeight ==> BODY对象高度 document.documentElement.clientWidth ==> 可见区域宽度 document.documentElement.clientHeight ==> 可见区域高度 FireFox中: document.body.clientWidth ==> BODY对象宽度 document.body.clientHeight ==> BODY对象高度 document.documentElement.clientWidth ==> 可见区域宽度 document.documentElement.clientHeight ==> 可见区域高度 Opera中: document.body.clientWidth ==> 可见区域宽度 document.body.clientHeight ==> 可见区域高度 document.documentElement.clientWidth ==> 页面对象宽度(即BODY对象宽度加上Margin宽) document.documentElement.clientHeight ==> 页面对象高度(即BODY对象高度加上Margin高) 没有定义W3C的标准,则 IE为: document.documentElement.clientWidth ==> 0 document.documentElement.clientHeight ==> 0 FireFox为: document.documentElement.clientWidth ==> 页面对象宽度(即BODY对象宽度加上Margin宽) document.documentElement.clientHeight ==> 页面对象高度(即BODY对象高度加上Margin高) Opera为: document.documentElement.clientWidth ==> 页面对象宽度(即BODY对象宽度加上Margin宽) document.documentElement.clientHeight ==> 页面对象高度(即BODY对象高度加上Margin高) 网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: document.body.offsetWidth (包括边线的宽) 网页可见区域高: document.body.offsetHeight (包括边线的高) 网页正文全文宽: document.body.scrollWidth 网页正文全文高: document.body.scrollHeight 网页被卷去的高: document.body.scrollTop 网页被卷去的左: document.body.scrollLeft 网页正文部分上: window.screenTop 网页正文部分左: window.screenLeft 屏幕分辨率的高: window.screen.height 屏幕分辨率的宽: window.screen.width 屏幕可用工作区高度: window.screen.availHeight 屏幕可用工作区宽度: window.screen.availWidth HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth scrollHeight: 获取对象的滚动高度。 scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离 scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离 scrollWidth:获取对象的滚动宽度 offsetHeight:获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度 offsetLeft:获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置 offsetTop:获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置 event.clientX 相对文档的水平座标 event.clientY 相对文档的垂直座标 event.offsetX 相对容器的水平坐标 event.offsetY 相对容器的垂直坐标 document.documentElement.scrollTop 垂直方向滚动的值 event.clientX+document.documentElement.scrollTop 相对文档的水平座标+垂直方向滚动的量
2017年11月26日
4 阅读
0 评论
0 点赞
2017-11-23
webpack开发和生产两个环境的配置
webpack.base.conf.jswebpack基本配置var path = require('path') var config = require('../config') var utils = require('./utils') var projectRoot = path.resolve(__dirname, '../') var env = process.env.NODE_ENV // check env & config/index.js to decide whether to enable CSS source maps for the // various preprocessor loaders added to vue-loader at the end of this file var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap) var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap) var useCssSourceMap = cssSourceMapDev || cssSourceMapProd // 配置文件的内容需要通过module.exports暴露 module.exports = { // 配置需要打包的入口文件,值可以是字符串、数组、对象。 // 1. 字符串: entry: './entry' // 2. 字符串: entry:[ './entry1','entry2'] (多入口) // 3. 对象: entry: {alert/index': path.resolve(pagesDir, `./alert/index/page`)} // 多入口书写的形式应为object,因为object,的key在webpack里相当于此入口的name, entry: { app: './src/main.js' }, output: { // 输出文件配置,output 输出有自己的一套规则,常用的参数基本就是这三个 // path: 表示生成文件的根目录 需要一个**绝对路径** path仅仅告诉Webpack结果存储在哪里 path: config.build.assetsRoot, // publicPath 参数表示的是一个URL 路径(指向生成文件的跟目录),用于生成css/js/图片/字体文件 // 等资源的路径以确保网页能正确地加载到这些资源. // “publicPath”项则被许多Webpack的插件用于在生产模式下更新内嵌到css、html文件里的url值. // 例如,在localhost(即本地开发模式)里的css文件中边你可能用“./test.png”这样的url来加载图片, // 但是在生产模式下“test.png”文件可能会定位到CDN上并且你的Node.js服务器可能是运行在HeroKu上边的。 // 这就意味着在生产环境你必须手动更新所有文件里的url为CDN的路径。 //开发环境:Server和图片都是在localhost(域名)下 //.image { // background-image: url('./test.png'); //} // 生产环境:Server部署下HeroKu但是图片在CDN上 //.image { // background-image: url('https://someCDN/test.png'); //} publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath, // filename 属性表示的是如何命名出来的入口文件,规则是一下三种: // [name] 指代入口文件的name,也就是上面提到的entry参数的key,因此,我们可以在name里利用/,即可达到控制文件目录结构的效果。 // [hash],指代本次编译的一个hash版本,值得注意的是,只要是在同一次编译过程中生成的文件,这个[hash].js //的值就是一样的;在缓存的层面来说,相当于一次全量的替换。 filename: '[name].js' }, // 用来配置依赖文件的匹配,如依赖文件的别名配置、模块的查找目录、默认查找的 // 文件后缀名 // resolve.root 该选型用来制定模块查找的根路径,必须为**绝对路径**,值可以 // 是路径字符串或者路径数组若是数组,则会依次查找 resolve: { extensions: ['', '.js', '.vue', '.json'], fallback: [path.join(__dirname, '../node_modules')], // 用来配置依赖文件的别名,值是一个对,该对象的键是别名,值是实际路径 alias: { 'vue$': 'vue/dist/vue.common.js', 'src': path.resolve(__dirname, '../src'), 'assets': path.resolve(__dirname, '../src/assets'), 'components': path.resolve(__dirname, '../src/components') } }, resolveLoader: { fallback: [path.join(__dirname, '../node_modules')] }, // 用来进行模块加载相关的配置 module: { preLoaders: [ { test: /\.vue$/, loader: 'eslint', include: projectRoot, exclude: /node_modules/ }, { test: /\.js$/, loader: 'eslint', include: projectRoot, exclude: /node_modules/ } ], loaders: [ // webpack拥有一个类似于插件的机制,名为Loader,通过Loader,webpack能够针对每一种特定的资源做出相应的处理 // 1.test参数用来指示当前配置项针对哪些资源,该值应是一个条件值(condition)。 // 2.exclude参数用来剔除掉需要忽略的资源,该值应是一个条件值(condition)。 // 3.include参数用来表示本loader配置仅针对哪些目录/文件,该值应是一个条件值(condition)。 // 而include参数则用来指示目录;注意同时使用这两者的时候,实际上是and的关系。 // 4.loader/loaders参数,用来指示用哪个或哪些loader来处理目标资源,这俩货 // 表达的其实是一个意思,只是写法不一样,我个人推荐用loader写成一行,多个 // loader间使用!分割,这种形式类似于管道的概念,又或者说是函数式编程。形 // 如loader: 'css?!postcss!less',可以很明显地看出,目标资源先经less-loader // 处理过后将结果交给postcss-loader作进一步处理,然后最后再交给css-loader。 { test: /\.vue$/, loader: 'vue' }, { test: /\.js$/, loader: 'babel', include: projectRoot, exclude: /node_modules/ }, { test: /\.json$/, loader: 'json' }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url', query: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url', query: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } }, // expose-loader,这个loader的作用是,将指定js模块export的变量声明为全局变量 { test: require.resolve('jquery'), // 此loader配置项的目标是NPM中的jquery loader: 'expose?$!expose?jQuery', // 先把jQuery对象声明成为全局变量`jQuery`,再通过管道进一步又声明成为全局变量`$` }, ] }, eslint: { formatter: require('eslint-friendly-formatter') }, vue: { loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }), // 解决.vue中文件style的部分一些特性解析,比如scoped postcss: [ require('autoprefixer')({ browsers: ['last 2 versions'] }) ] } }webpack.dev.conf.jsvar config = require('../config') var webpack = require('webpack') var merge = require('webpack-merge') var utils = require('./utils') var baseWebpackConfig = require('./webpack.base.conf') var HtmlWebpackPlugin = require('html-webpack-plugin') // add hot-reload related code to entry chunks Object.keys(baseWebpackConfig.entry).forEach(function (name) { baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) }) module.exports = merge(baseWebpackConfig, { module: { loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) }, // eval-source-map is faster for development devtool: '#eval-source-map', plugins: [ // DefinePlugin 是webpack 的内置插件,该插件可以在打包时候替换制定的变量 // new webpack.DefinePlugin({ 'process.env': config.dev.env }), // https://github.com/glenjamin/webpack-hot-middleware#installation--usage new webpack.optimize.OccurrenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }), // 可以自动加载当前模块依赖的其他模块并已制定别名注入到当前的模块中,引入jq // 在网上看到的文章,救了我的命 ProvidePlugin + expose-loader 引入jq // // 如果你把jQuery看做是一个普通的js模块来加载(要用到jQuery的模块统统先require // 后再使用),那么,当你加载老式jQuery插件时,往往会提示找不到jQuery实例 // 有时候是提示找不到$),这是为啥呢? // 要解释这个问题,就必须先稍微解释一下jQuery插件的机制:jQuery插件是通过 // jQuery提供的jQuery.fn.extend(object)和jQuery.extend(object)这俩方法,来 // 把插件本身实现的方法挂载到jQuery(也即$)这个对象上的。传统引用jQuery及 // 其插件的方式是先用<script>加载jQuery本身,然后再用同样的方法来加载其插件; // jQuery会把jQuery对象设置为全局变量(当然也包括了$),既然是全局变量,那么 // 插件们很容易就能找到jQuery对象并挂载自身的方法了。 // // 而webpack作为一个遵从模块化原则的构建工具,自然是要把各模块的上下文环境给 // 分隔开以减少相互间的影响;而jQuery也早已适配了AMD/CMD等加载方式,换句话说, // 我们在require jQuery的时候,实际上并不会把jQuery对象设置为全局变量。说到 // 这里,问题也很明显了,jQuery插件们找不到jQuery对象了,因为在它们各自的上下 // 文环境里,既没有局部变量jQuery(因为没有适配AMD/CMD,所以就没有相应的requi // re语句了),也没有全局变量jQuery。 // // A: ProvidePlugin的机制是:当webpack加载到某个js模块里,出现了未定义且名称符合 // (字符串完全匹配)配置中key的变量时,会自动require配置中value所指定的js模块 // expose-loader,这个loader的作用是,将指定js模块export的变量声明为全局变量。 // // B:externals 调用jq // externals是webpack配置中的一项,用来将某个全局变量“伪装”成某个js模块的exports, // 如下面这个配置: // externals: {'jquery': 'window.jQuery',}, // 那么,当某个js模块显式地调用var $ = require('jquery')的时候,就会把window, // jQuery返回给它,与上述ProvidePlugin + expose-loader的方案相反,此方案是先用 // <script>加载的jQuery满足老式jQuery插件的需要,再通过externals将其转换成符合 // 模块化要求的exports。 new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery", 'window.$': 'jquery', }) ] })webpack.prod.conf.jsvar path = require('path') var config = require('../config') var utils = require('./utils') var webpack = require('webpack') var merge = require('webpack-merge') var baseWebpackConfig = require('./webpack.base.conf') var ExtractTextPlugin = require('extract-text-webpack-plugin') var HtmlWebpackPlugin = require('html-webpack-plugin') var env = config.build.env var webpackConfig = merge(baseWebpackConfig, { module: { loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true }) }, devtool: config.build.productionSourceMap ? '#source-map' : false, output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') }, vue: { loaders: utils.cssLoaders({ sourceMap: config.build.productionSourceMap, extract: true }) }, // webpack插件位置,有固定的用法 // 1. 利用Plugin的初始方法并传入Plugin预设的参数进行初始化,生成一个实例。 // 2. 将此实例插入到webpack配置文件中的plugins参数(数组类型)里即可。 // // 1. plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }), new webpack.optimize.OccurrenceOrderPlugin(), // extract css into its own file new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')), // generate dist index.html with correct asset hash for caching. // you can customize output by editing /index.html // see https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ // filename 生成网页的HTML名字,可以使用/来控制文件文件的目录结构,最 // 终生成的路径是基于webpac配置的output.path的 filename: config.build.index, template: 'index.html', inject: true, // inject,指示把加载js文件用的<script>插入到哪里,默认是插到<body> // 的末端,如果设置为'head',则把<script>插入到<head>里。 minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), // 如果文件是多入口的文件,可能存在,重复代码,把公共代码提取出来,又不会重复下载公共代码了 // (多个页面间会共享此文件的缓存) // CommonsChunkPlugin的初始化常用参数有解析? // name: 这个给公共代码的chunk唯一的标识 // filename,如何命名打包后生产的js文件,也是可以用上[name]、[hash]、[chunkhash] // minChunks,公共代码的判断标准:某个js模块被多少个chunk加载了才算是公共代码 new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: function (module, count) { // any required modules inside node_modules are extracted to vendor return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), // extract webpack runtime and module manifest to its own file in order to // prevent vendor hash from being updated whenever app bundle is updated new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', chunks: ['vendor'] }) ] }) if (config.build.productionGzip) { var CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) ) } module.exports = webpackConfig
2017年11月23日
4 阅读
0 评论
0 点赞
2017-11-20
14 个你可能不知道的 JavaScript 调试技巧
协作翻译原文:The 14 JavaScript debugging tips you probably didn't know链接:https://raygun.com/javascript-debugging-tips译者:暖冰, 边城, 无若, 王练了解你的工具可以极大的帮助你完成任务。尽管 JavaScript 的调试非常麻烦,但在掌握了技巧 (tricks) 的情况下,你依然可以用尽量少的的时间解决这些错误 (errors) 和问题 (bugs) 。我们会列出14个你可能不知道的调试技巧, 但是一旦知道了,你就会迫不及待的想在下次需要调试 JavaScript 代码的时候使用它们!现在开始。虽然许多技巧也可以用在别的检查工具上,但大部分的技巧是用在 Chrome Inspector 和 Firefox 上的。‘debugger;’‘debugger’ 是 console.log 之外我最喜欢的调试工具,简单暴力。只要把它写到代码里,Chrome 运行的时候就会自动自动停在那。你甚至可以用条件语句把它包裹起来,这样就可以在需要的时候才执行它。把 objects 输出成表格有时候你可能有一堆对象需要查看。你可以用 console.log 把每一个对象都输出出来,你也可以用 console.table 语句把它们直接输出为一个表格!输出结果:试遍所有的尺寸虽然把各种各样的手机都摆在桌子上看起来很酷,但这却很不现实。为什么不选择直接调整界面大小呢? Chrome 浏览器提供了你所需要的一切。 进入检查面板点击 ‘切换设备模式’ 按钮,这样你就可以调整视窗的大小了!如何快速定位 DOM 元素在元素面板上标记一个 DOM 元素并在 concole 中使用它。Chrome Inspector 的历史记录保存最近的五个元素,最后被标记的元素记为 $0,倒数第二个被标记的记为 $1,以此类推。如果你像下面那样把元素按顺序标记为 ‘item-4′, ‘item-3’, ‘item-2’, ‘item-1’, ‘item-0’ ,你就可以在 concole 中获取到 DOM 节点:用 console.time() 和 console.timeEnd() 测试循环耗时当你想知道某些代码的执行时间的时候这个工具将会非常有用,特别是当你定位很耗时的循环的时候。你甚至可以通过标签来设置多个 timer 。demo 如下:运行结果:6.获取函数的堆栈轨迹信息你可能知道 JavaScript 框架会产生很多的代码--迅速的。它创建视图触发事件而且你最终会想知道函数调用是怎么发生的。因为 JavaScript 不是一个很结构化的语言,有时候很难完整的了解到底发生了什么以及什么时候发生的。 这个时候就轮到 console.trace(在终端的话就只有 trace )出场来调试 JavaScript了 。假设你现在想看 car 实例在第33行调用 funcZ 函数的完整堆栈轨迹信息:第33行会输出:你可以看到func1调用了func2, func2又调用了func4。Func4 创建了Car的实例,然后调用了方法car.funcX,等等。尽管你感觉你对自己的脚本代码非常了解,这种分析依然是有用的。 比如你想优化你的代码。 获取到堆栈轨迹信息和一个所有相关函数的列表。每一行都是可点击的,你可以在他们中间前后穿梭。 这感觉就像特地为你准备的菜单。格式化代码使调试 JavaScript 变得容易有时候你发现产品有一个问题,而 source map 并没有部署到服务器。不要害怕。Chrome 可以格式化 JavaScript 文件,使之易读。格式化出来的代码在可读性上可能不如源代码 —— 但至少你可以观察到发生的错误。点击源代码查看器下面的美化代码按钮 {} 即可。快速找到调试函数来看看怎么在函数中设置断点。通常情况下有两种方法:在查看器中找到某行代码并在此添加断点在脚本中添加 debugger这两种方法都必须在文件中找到需要调试的那一行。使用控制台是不太常见的方法。在控制台中使用 debug(funcName),代码会在停止在进入这里指定的函数时。这个操作很快,但它不能用于局部函数或匿名函数。不过如果不是这两种情况下,这可能是调试函数最快的方法。(注意:这里并不是在调用 console.debug 函数)。在控制台中输入 debug(car.funcY),脚本会在调试模式下,进入 car.funcY 的时候停止运行:屏蔽不相关代码如今,经常在应用中引入多个库或框架。其中大多数都经过良好的测试且相对没有缺陷。但是,调试器仍然会进入与此调试任务无关的文件。解决方案是将不需要调试的脚本屏蔽掉。当然这也可以包括你自己的脚本。 点此阅读更多关于调试不相关代码(http://raygun.com/blog/javascript-debugging-with-black-box/)。在复杂的调试过程中寻找重点在更复杂的调试中,我们有时需要输出很多行。你可以做的事情就是保持良好的输出结构,使用更多控制台函数,例如 Console.log,console.debug,console.warn,console.info,console.error 等等。然后,你可以在控制台中快速浏览。但有时候,某些JavaScrip调试信息并不是你需要的。现在,可以自己美化调试信息了。在调试JavaScript时,可以使用CSS并自定义控制台信息:console.todo = function(msg) {console.log(‘ % c % s % s % s‘, ‘color: yellow; background - color: black;’, ‘–‘, msg, ‘–‘);}console.important = function(msg) {console.log(‘ % c % s % s % s’, ‘color: brown; font - weight: bold; text - decoration: underline;’, ‘–‘, msg, ‘–‘);}console.todo(“This is something that’ s need to be fixed”);console.important(‘This is an important message’);输出:例如:在console.log()中, 可以用%s设置字符串,%i设置数字,%c设置自定义样式等等,还有很多更好的console.log()使用方法。 如果使用的是单页应用框架,可以为视图(view)消息创建一个样式,为模型(models),集合(collections),控制器(controllers)等创建另一个样式。也许还可以像 wlog,clog 和 mlog 一样发挥你的想象力!查看具体的函数调用和它的参数在 Chrome 浏览器的控制台(Console)中,你会把你的注意力集中在具体的函数上。每次这个函数被调用,它的值就会被记录下来。然后输出:这是查看将哪些参数传递到函数的一种很好的方法。但我必须说,如果控制台能够告诉我们需要多少参数,那就好了。在上面的例子中,函数1期望3个参数,但是只有2个参数被传入。如果代码没有在代码中处理,它可能会导致一个 bug 。在控制台中快速访问元素在控制台中执行 querySelector 一种更快的方法是使用美元符。$(‘css-selector’) 将会返回第一个匹配的 CSS 选择器。$$(‘css-selector’) 将会返回所有。如果你使用一个元素超过一次,它就值得被作为一个变量。Postman 很棒(但 Firefox 更快)很多开发人员都使用 Postman 来处理 Ajax 请求。Postman 真不错,但每次都需要打开新的浏览器窗口,新写一个请求对象来测试。这确实有点儿烦人。有时候直接使用在用的浏览器会更容易。这样的话,如果你想请求一个通过密码保证安全的页面时,就不再需要担心验证 Cookie 的问题。这就是 Firefox 中编辑并重新发送请求的方式。打开探查器并进入网络页面,右键单击要处理的请求,选择编辑并重新发送。现在你想怎么改就怎么改。可以修改头信息,也可以编辑参数,然后点击重新发送即可。现在我发送了两次同一个请求,但使用了不同的参数:节点变化时中断DOM 是个有趣的东西。有时候它发生了变化,但你却并不知道为什么会这样。不过,如果你需要调试 JavaScript,Chrome 可以在 DOM 元素发生变化的时候暂停处理。你甚至可以监控它的属性。在 Chrome 探查器上,右键点击某个元素,并选择中断(Break on)选项来使用:
2017年11月20日
2 阅读
0 评论
0 点赞
2017-11-14
时间格式化
const newDate = str => { if (str === null) return null; if (str === undefined) return new Date(); if (str.constructor != String) return new Date(str); let $ = str.match(/^\s*(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)\s*$/); return $ && new Date($[1], $[2] - 1, $[3], $[4], $[5], $[6]) || new Date(str); } /** * * 格式化时间 * * @param {String} str * @param {String} fmt "yyyy-MM-dd hh:mm:ss" "yyyy-MM-dd" * @returns 格式化后的时间 */ const formatDate = (str, fmt) => { if (!Boolean(str)) { return "" } const now = newDate(str); let o = { "M+": now.getMonth() + 1, //月份 "d+": now.getDate(), //日 "h+": now.getHours(), //小时 "m+": now.getMinutes(), //分 "s+": now.getSeconds(), //秒 "q+": Math.floor((now.getMonth() + 3) / 3), //季度 "S": now.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (now.getFullYear() + "").substr(4 - RegExp.$1.length)); } for (let k in o) { if (new RegExp("(" + k + ")").test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); } } return fmt; } export { formatDate, newDate }
2017年11月14日
5 阅读
0 评论
0 点赞
1
2
3