Fork me on GitHub

使用教程

易懂的 webpack 使用教程

原文链接:https://www.zfanw.com/blog/webpack-tutorial.html

  • 1安装 webpack

  • 2初始化项目

  • 3webpack 配置

  • 4实时刷新

  • 5第三方库

  • 6模块化

  • 7打包、构建

我还记得我刚接触 webpack 时的感受:一头雾水。

我是说,我真的不太关心 js 文件要配哪些加载器。我只想快一点把开发环境搭起来干活。总之,几经折腾,我嫌麻烦放弃了 webpack 这个方案。

但今天回头去看,其实它并没那么复杂。

那么,webpack 是什么?

MODULE BUNDLER
它是这么自称的,模块打包器。

在 webpack 里,所有类型的文件都可以是模块,包括我们最常见的 JavaScript,及 CSS 文件、图片、json 文件等等。通过 webpack 的各种加载器,我们可以更高效地管理这些文件。

安装 webpack

我们通过npm在全局环境下安装 webpack:

npm install webpack -g

安装完成后,我们可以使用 webpack 命令,执行

webpack --help

能够查看 webpack 提供的所有命令。

不过,建议在项目下安装一份局域的 webpack:

npm install webpack --save-dev

如果觉得 npm 安装太慢,可以尝试 npm 的替代工具 ied – 我的使用经历,它的速度比 npm 快太多了。

初始化项目

安装好 webpack 后,我们要怎么开始一个项目?

如果你用过 grunt.js、gulpjs 一类工具,它们可以借助 yeoman 来初始化项目。webpack 的情况不太一样,我们可以把它当作 node.js 项目来初始化。当然,借用一些模板会更省事,比如 react transform boilerplate。

但这里还是聊聊如何手动初始化一个 webpack 项目。

1 创建一个 package.json 文件,用于保存项目版本、依赖关系等

npm init -y

2 在当前目录下安装 webpack

npm install webpack --save-dev

这时,我们的项目下有两个内容:

package.json 文件
node_modules 文件夹

我们还需要一个 index.html 文件,示例如下:

<!DOCTYPE html>
  <html lang="en">
  <head>
  <meta charset="UTF-8">
  <title>webpack 教程</title>
  </head>
  <body>
  </body>
  </html>

现在,我们可以通过 live-server 等访问到 index.html 页面。

目前页面上还是一片空白,除了一个标题。

webpack 配置

单页面应用里,项目通常会有一个入口(entry)文件,假设是 main.js,我们通过配置 webpack 来指明它的位置。

首先,在项目根目录新建一个webpack.config.js,这是 webpack 默认的配置文件名称,添加以下内容:

module.exports = {
entry: './main.js'
  };

尝试在项目根目录执行webpack,会提示我们,

Output filename not configured.

因为我们只是设定了入口(entry),还没有指定一个输出文件的路径与名称。

webpack.config.js 中添加一个 output

module.exports = {
entry: './main.js',
output: {
    path: __dirname, // 输出文件的保存路径
    filename: 'bundle.js' // 输出文件的名称
}
}

现在在项目里执行 webpack 命令,我们的根目录下会多出一个bundle.js 文件:

https://www.zfanw.com/blog/wp-content/uploads/2015/06/Screen-Shot-2015-06-05-at-20.53.08.png

接下来,在 index.html 中引用 bundle.js 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webpack 教程</title>
</head>
<body>
  <script src="./bundle.js"></script> <!-- 在 index.html 文件中添加这一行代码 -->
</body>
</html> 

大功告成。

这是 webpack 一类工具的特点,它们在 HTML 文件直接引用构建后的 js 文件,而不是源文件。

当然,这可能会引发性能问题,毕竟,如果每一点文件修改都会导致整个 bundle.js 文件重新构建的话,碰上大一点的项目,有几千个源文件要编译,编译速度可能很慢。webpack 有它的解决办法,具体参见它的文档。

实时刷新

在 html 文件中引用 bundle.js 文件后,我们有几个问题需要解决。

  1. main.js 或它所引用的模块的变化如何通知 webpack,重新生成 bundle.js

非常简单,在根目录下执行 webpack –watch 就可以监控目录下的文件变化并实时重新构建。

  1. 上面只是实时构建,我们该如何把结果通知给浏览器页面,让 HTML 页面上的 bundle.js 内容保持最新

webpack 提供了 webpack-dev-server 解决实时刷新页面的问题,同时解决实时构建的问题。

安装 webpack-dev-server

  1. 在全局环境中安装 webpack-dev-server:

    npm install webpack-dev-server -g

  2. 在项目根目录下执行命令:

    $ webpack-dev-server

这样,我们就可以在默认的 http://localhost:8080 网址上打开我们的 index.html。

此时,我们可能认为事情是按以下顺序发生的,

  1. js 文件修改
  2. webpack-dev-server 监控到变化
  3. webpack 在内存中重新构建 bundle.js
  4. webpack-dev-server 保证页面引用的 bundle.js 文件与内存中一致

但不幸的是,我们「自以为是」了。http://localhost:8080/index.html 对 js 文件的变化无动于衷。

webpack-dev-server 提供了两种模式用于自动刷新页面:

  1. iframe 模式

    我们不访问 http://localhost:8080,而是访问 http://localhost:8080/webpack-dev-server/ index.html

  2. inline 模式

    在命令行中指定该模式,webpack-dev-server --inline。这样http://localhost:8080/index.html页面就会在 js 文件变化后自动刷新了。

以上说的两个页面自动刷新的模式都是指刷新整个页面,相当于点击了浏览器的刷新按钮。

webpack-dev-server 还提供了一种 –hot 模式,属于较高阶的应用。

第三方库

webpack 并不是包管理器,所以如果我们要使用第三方库,需要借助 npm。比如,在项目里安装 jQuery

npm install jquery --save

这样我们在当前项目目录下安装了 jQuery,并将它写入 package.json 里的依赖里。

模块化

模块化 JavaScript

如果我想用 ES6 的方式引入 jQuery 模块,比如:

import $ from 'jquery'

怎么办?浏览器目前还不提供原生支持,webpack 原生也仅支持 CommonJS 的那种写法,但借助 babel-loader ,我们可以加载 es6 模块:

1.安装 babel-loader

npm install babel-loader babel-core babel-preset-es2015 --save-dev 

2.配置 webpack.config.js

module.exports 值中添加 module

module.exports = {
  entry: {
      app: ['./main.js']
  },
  output: {
      filename: 'bundle.js'
  },
  module: {
      loaders: [{
      test: /\.js$/,
      loaders: ['babel?presets[]=es2015'],
      exclude: /node_modules/
      }]
  }
}

这样我们就可以在我们的 js 文件中使用 ES6 语法,babel-loader 会负责编译成浏览器可以识别的格式。

CSS 加载器

我们可以按传统方法使用 CSS,即在 HTML 文件中添加:

<link rel="stylesheet" href="style/app.css">

但 webpack 里,CSS 同样可以模块化,使用 import 导入。

因此我们不再使用 link 标签来引用 CSS,而是通过 webpack 的 style-loader 及 css-loader。前者将 css 文件以 标签插入 头部,后者负责解读、加载 CSS 文件。

1.安装 CSS 相关的加载器

npm install style-loader css-loader --save-dev

2.配置 webpack.config.js 文件

 {
module: {
    loaders: [
        { test: /\.css$/, loaders: ['style', 'css'] }
    ]
}
  } 

3.在 main.js 文件中引入 css

import'./style/app.css';

这样,在执行 webpack 后,我们的 CSS 文件就会被打包进 bundle.js 文件中,如果不想它们被打包进去,可以使用 extract text 扩展。

模块化 CSS

上一步里,我们 import 到 JavaScript 文件中的 CSS 文件中的 CSS 在打包后是仍然是全局的,也就是说,我们只是换了种加载 CSS 的方式,在书写 CSS 的时候,还是需要注意使用命名规范,比如使用 BEM,否则全局环境 CSS 类的冲突等问题不会消失。

这里,webpack 做了一个模块化 CSS 的尝试,真正意思上的「模块化」,即 CSS 类不会泄露到全局环境中,而只会定义在 UI 模块内 – 类似 react.js 这类模块,或者 web components。

autoprefixer

我们在写 CSS 时,按 CSS 规范写,构建时利用 autoprefixer 可以输出 -webkit、-moz 这样的浏览器前缀,webpack 同样是通过 loader 提供该功能。

1.安装 autoprefixer-loader

npm install autoprefixer-loader --save-dev

2.配置 webpack.config.js

 loaders: [{
test: /\.css$/,
loader: 'style!css!autoprefixer?{browsers:["last 2 version", "> 1%"]}',
  }]

3.重启 webpack-dev-server

假如我们在 CSS 中写了 body { display: flex; } 规则,再查看 bundle.js 文件的话,我们能看到类似如下的代码:

body {\n\tdisplay: -webkit-box;\n\tdisplay: -webkit-flex;\n\tdisplay: -ms-flexbox;    \n\tdisplay: flex;\n}

图片

图片同样可以是模块,但使用的是 file loader 或者 url loader,后者会根据定义的大小范围来判断是否使用 data url。

import loadingIMG from 'file!../img/loading.gif'

 React.render(<img src={loadingIMG} />, document.getElementById('app'));

打包、构建

项目结束后,代码要压缩、混淆、合并等,只需要在命令行执行:

$ webpack

即可,webpack 根据 webpack.config.js 文件中的配置路径、构建文件名生成相应的文件。通常,我们会额外定义一个专门用于生产环境的配置文件,比如 webpack.production.config.js,其中可以做许多代码优化。

代码段

推荐10 个短小却超实用的 JavaScript 代码段

JavaScript正变得越来越流行,它已经成为前端开发的第一选择,并且利用基于JavaScript语言的NodeJS,我们也可以开发出高性能的后端服务,甚至我还看到在硬件编程领域也出现了JavaScript的身影。JavaScript正在逐渐进化为一门全能的开发语言。

但用好JavaScript并不容易,你除了需要掌握它的语法并知道如何写出高质量的代码之外,还需要了解如何解决那些几乎在每个项目中都会遇到的需求场景,比如:判断日期,高亮文本,限制字符数等等,有很多第三方库可以解决这些问题,但这些库可能并非只是为解决这一个问题而创建的,这意味着你需要引入了很多无关的代码,这将使你的整个系统变得臃肿,而且也会影响到系统的性能。我的做法是,收集和使用那些常见的JavaScript代码段,并在需要时,尽可能首先使用它们。下面便是我收集的10段实用JavaScript代码,基于它们你还可以创造出更强大的JS插件或功能函数。

1. 判断日期是否有效

JavaScript中自带的日期函数还是太过简单,很难满足真实项目中对不同日期格式进行解析和判断的需要。JQuery也有一些第三方库来使日期相关的处理变得简单,但有时你可能只需要一个非常简单的函数,而不想引入一个庞大的第三方库。这时,你可以使用下面这段日期校验代码,它允许你自定义日期格式并进行日期有效性的校验。

function isValidDate(value, userFormat) {

  // Set default format if format is not provided
  userFormat = userFormat || 'mm/dd/yyyy';

  // Find custom delimiter by excluding
  // month, day and year characters
  var delimiter = /[^mdy]/.exec(userFormat)[0];

  // Create an array with month, day and year
  // so we know the format order by index
  var theFormat = userFormat.split(delimiter);

  // Create array from user date
  var theDate = value.split(delimiter);

  function isDate(date, format) {
    var m, d, y, i = 0, len = format.length, f;
    for (i; i < len; i++) {
      f = format[i];
      if (/m/.test(f)) m = date[i];
      if (/d/.test(f)) d = date[i];
      if (/y/.test(f)) y = date[i];
    }
    return (
          m > 0 && m < 13 &&
      y && y.length === 4 &&
      d > 0 &&
      // Check if it's a valid day of the month
      d <= (new Date(y, m, 0)).getDate()
    );
  }

  return isDate(theDate, theFormat);
}


使用方法:

下面这个调用返回false,因为11月份没有31天

isValidDate('dd-mm-yyyy', '31/11/2012')

2.获取一组元素的最大宽度或高度
下面这个函数,对于需要进行动态排版的开发人员非常有用。

var getMaxHeight = function ($elms) {
  var maxHeight = 0;
  $elms.each(function () {
// In some cases you may want to use outerHeight() instead
var height = $(this).height();
if (height > maxHeight) {
  maxHeight = height;
}
  });
  return maxHeight;
};

3.高亮文本
有很多JQuery的第三方库可以实现高亮文本的功能,但我更喜欢用下面这一小段JavaScript代码来实现这个功能,它非常短小,而且可以根据我的需要去进行灵活的修改,而且可以自己定义高亮的样式。下面这两个函数可以帮助你创建自己的文本高亮插件。

function highlight(text, words, tag) {

  // Default tag if no tag is provided
  tag = tag || 'span';

  var i, len = words.length, re;
  for (i = 0; i < len; i++) {
    // Global regex to highlight all matches
    re = new RegExp(words[i], 'g');
    if (re.test(text)) {
      text = text.replace(re, '<'+ tag +' class="highlight">$&</'+ tag +'>');
    }
  }

  return text;
}

你同样会需要取消高亮的函数:

function unhighlight(text, tag) {
  // Default tag if no tag is provided
  tag = tag || 'span';
  var re = new RegExp('(<'+ tag +'.+?>|<\/'+ tag +'>)', 'g');
  return text.replace(re, '');
}

使用方法:

$('p').html( highlight(
$('p').html(), // the text
['foo', 'bar', 'baz', 'hello world'], // list of words or phrases to highlight
'strong' // custom tag
));

4.文字动效
有时你会希望给你的一段文字增加动效,让其中的每个字都动起来。你可以使用下面这段jQuery插件代码来达到这个效果。当然你需要结合一个CSS3 transition样式来达到更好的效果。

$.fn.animateText = function(delay, klass) {

  var text = this.text();
  var letters = text.split('');

  return this.each(function(){
    var $this = $(this);
    $this.html(text.replace(/./g, '<span class="letter">$&</span>'));
    $this.find('span.letter').each(function(i, el){
      setTimeout(function(){ $(el).addClass(klass); }, delay * i);
    });
  });

};

使用方法:

$('p').animateText(15, 'foo');

5.逐个隐藏元素
下面这个jQuery插件可以根据你设置的步长(间隔时间)来逐个隐藏一组元素。在列表元素的重新加载中使用,可以达到很好的效果。

$.fn.fadeAll = function (ops) {
  var o = $.extend({
delay: 500, // delay between elements
speed: 500, // animation speed
ease: 'swing' // other require easing plugin
  }, ops);
  var $el = this;
  for (var i=0, d=0, l=$el.length; i<l; i++, d+=o.delay) {
$el.eq(i).delay(d).fadeIn(o.speed, o.ease);
  }
  return $el;
}

使用方法:

$(elements).fadeAll({ delay: 300, speed: 300 });

6.限制文本字数
下面这端脚本允许你根据给定的字符长度截取文本,如果文本被截取,那么它的后面会自动带上省略号。

function excerpt(str, nwords) {
  var words = str.split(' ');
  words.splice(nwords, words.length-1);
  return words.join(' ') +
(words.length !== str.split(' ').length ? '…' : '');
}

7.判断相应式布局中当前适配度
目前很多设计已经采用了响应式布局来适配网站或应用在不同设备上的显示。你经常需要在代码中判断当前处于哪一个屏幕适配度下。

function isBreakPoint(bp) {
  // The breakpoints that you set in your css
  var bps = [320, 480, 768, 1024];
  var w = $(window).width();
  var min, max;
  for (var i = 0, l = bps.length; i < l; i++) {
    if (bps[i] === bp) {
      min = bps[i-1] || 0;
      max = bps[i];
      break;
    }
  }
  return w > min && w <= max;
}

使用方法:

if ( isBreakPoint(320) ) {
  // breakpoint at 320 or less
}
if ( isBreakPoint(480) ) {
  // breakpoint between 320 and 480
}
…

8.全局计数
在一些游戏或广告场景中,你需要记录用户在当前页面上点击某一个按钮的次数,这时你可以使用jQuery的.data()函数来处理:

$(element)
.data('counter', 0) // begin counter at zero
.click(function() {
    var counter = $(this).data('counter'); // get
    $(this).data('counter', counter + 1); // set
    // do something else...
});

9.嵌入优酷视频

function embedYouku(link, ops) {

  var o = $.extend({
       width: 480,
    height: 320,
    params: ''
  }, ops);

  var id = /\?v\=(\w+)/.exec(link)[1];

  return '<embed allowFullScreen="true" id="embedid"  quality="high"     width="'+o.width+'" height="'+o.height+'" align="middle"     allowScriptAccess="always" type="application/x-shockwave-flash" src="'+id    +'?'+o.ops'"';
}

使用方法:

embedYouku(
  'http://static.youku.com/v/swf/qplayer.swf', 
      {'winType=adshow&VideoIDS=XMTE3NzQ0NTky&isAutoPlay=false&isShowRelatedVideo=false'}
);

10.创建动态菜单或下拉列表
在很多场景中,我们都需要动态地创建菜单、下拉列表或列表项。下面是一段最基础的代码实现上面的功能,你可以根据实际需要进行相应的扩展。

function makeMenu(items, tags) {

  tags = tags || ['ul', 'li']; // default tags
  var parent = tags[0];
  var child = tags[1];

  var item, value = '';
  for (var i = 0, l = items.length; i < l; i++) {
item = items[i];
// Separate item and value if value is present
if (/:/.test(item)) {
  item = items[i].split(':')[0];
  value = items[i].split(':')[1];
    }
    // Wrap the item in tag
    items[i] = '<'+ child +' '+
      (value && 'value="'+value+'"') +'>'+ // add value if present
    item +'</'+ child +'>';
  }

  return '<'+ parent +'>'+ items.join('') +'</'+ parent +'>';
}

使用方法:

// Dropdown select month
makeMenu(
  ['January:JAN', 'February:FEB', 'March:MAR'], // item:value
  ['select', 'option']
);

// List of groceries
makeMenu(
  ['Carrots', 'Lettuce', 'Tomatos', 'Milk'],
  ['ol', 'li']
);

文/技匠(简书签约作者)
原文链接:http://www.jianshu.com/p/3ef822ec5a63
著作权归作者所有,转载请联系作者获得授权,并标注“简书签约作者”。

总结:
以上只是那些实用JavaScript代码段中的一小部分,我也建议你平时注意收集或自己编写这样的基础代码段,它们能在很多项目中使用或通过一些改造提供更完善的功能,使用这些代码段将为你节省下大量的开发时间。

本文转载自 http://www.jianshu.com/p/3ef822ec5a63

文/技匠(简书签约作者)
原文链接:http://www.jianshu.com/p/3ef822ec5a63
著作权归作者所有,转载请联系作者获得授权,并标注“简书签约作者”。

深入浅出JSONP--解决ajax跨域问题

JSONP–解决ajax跨域问题

同源策略

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当一个百度浏览器执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。

JSON和JSONP

JSONP和JSON好像啊,他们之间有什么联系吗?

  JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。对于JSON大家应该是很了解了吧,不是很清楚的朋友可以去json.org上了解下,简单易懂。

  JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。–来源百度

  JSONP就像是JSON+Padding一样(Padding这里我们理解为填充), 我们先看下面的小例子然后再详细介绍。      

跨域的简单原理

光看定义还不是很明白,那首先我们先来手动做个简单易懂的小测试。新建一个asp.net的web程序,添加sample.html网页和一个test.js文件,代码如下:

sample.html的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/        TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" >
  <head>
  <title>test</title>
  <script type="text/javascript" src="test.js"></script>
  </head>
  <body>
  </body>
  </html>

test.js的代码:

alert("success");

打开sample.html后会跳出”success”这样的这样的信息框,这似乎并不能说明什么, 跨域问题到底怎么解决呢?好,现在我们模拟下非同源的环境,刚才我们不是已经用Visual Studio新建了一个Web程序吗(这里我们叫A程序),现在我们再打开一个新的Visual Studio再新建一个Web程序(B程序),将我们的之前的test.js文件从A程序中移除然后拷贝到B程序中。两个程序都运行起来后,Visual Studio会启动内置服务器,假设A程序是localhost:20001,B程序是localhost:20002,这就模拟了一个非同源的环境了(虽然域名相同但端口号不同,所以是非同源的)。

  OK,我们接下来应该改下sample.html里的代码,因为test.js文件在B程序上了,url也就变成了localhost:20002。

sample.html部分代码:

<script type="text/javascript" src="http://localhost:20002/test.js"></script>

请保持AB两个Web程序的运行状态,当你再次刷新localhost:20001/sample.html的时候,和原来一样跳出了”success”的对话框,是的,成功访问到了非同源的localhost:20002/test.js这个所谓的远程服务了。到了这一步,相信大家应该已经大概明白如何跨域访问了的原理了。

<script>标签的src属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行。

JSONP的实现模式–CallBack

刚才的小例子讲解了跨域的原理,我们回上去再看看JSONP的定义说明中讲到了javascript callback的形式。那我们就来修改下代码,如何实现JSONP的javascript callback的形式。

程序A中sample的部分代码:

<script type="text/javascript">
//回调函数
function callback(data) {
    alert(data.message);
    }
    </script>
    <script type="text/javascript" src="http://localhost:20002/test.js"></script>

程序B中test.js的代码:

//调用callback函数,并以json数据形式作为阐述传递,完成回调
callback({message:"success"}); 

这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义吧。

一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。

程序A中sample的部分代码:

<script type="text/javascript">
 function callback(data) {
  alert(data.message);
 }
 //添加<script>标签的方法
 function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}

window.onload = function(){
addScriptTag("http://localhost:20002/test.js");
  }
</script>

程序B的test.js代码不变,我们再执行下程序,是不是和原来的一样呢。如果我们再想调用一个远程服务的话,只要添加addScriptTag方法,传入远程服务的src值就可以了。这里说明下为什么要将addScriptTag方法放入到window.onload的方法里,原因是addScriptTag方法中有句document.body.appendChild(script);,这个script标签是被添加到body里的,由于我们写的javascript代码是在head标签中,document.body还没有初始化完毕呢,所以我们要通过window.onload方法先初始化页面,这样才不会出错。

  上面的例子是最简单的JSONP的实现模型,不过它还算不上一个真正的JSONP服务。我们来看一下真正的JSONP服务是怎么样的,比如Google的ajax搜索接口:http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=?&callback=?

  q=?这个问号是表示你要搜索的内容,最重要的是第二个callback=?这个是正如其名表示回调函数的名称,也就是将你自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调。有点罗嗦了,还是看看实现代码吧:

<script type="text/javascript">
 //添加<script>标签的方法
function addScriptTag(src){
 var script = document.createElement('script');
 script.setAttribute("type","text/javascript");
 script.src = src;
 document.body.appendChild(script);
  }

 window.onload = function(){
 //搜索apple,将自定义的回调函数名result传入callback参数中
 addScriptTag("http://ajax.googleapis.com/ajax/services/search/web?    v=1.0&q=apple&callback=result");

 }
 //自定义的回调函数result
 function result(data) {
//我们就简单的获取apple搜索结果的第一条记录中url数据
 alert(data.responseData.results[0].unescapedUrl);
}
</script>    

像这样的JSONP服务还有很多(以下信息来自使用 JSONP 实现跨域通信,第 1 部分: 结合 JSONP 和 jQuery 快速构建强大的 mashup):

Digg API:来自 Digg 的头条新闻:

  http://services.digg.com/stories/top?appkey=http%3A%2F%2Fmashup.com&type=javascript&callback=?

Geonames API:邮编的位置信息:

  http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?

Flickr JSONP API:载入最新猫的图片:

  http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?

Yahoo Local Search API:在邮编为 10504 的地区搜索比萨:

  http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza&zip=10504&results=2&output=json&callback=?

接下来我们自己来创建一个简单的远程服务,实现和上面一样的JSONP服务。还是利用Web程序A和程序B来做演示,这次我们在程序B上创建一个MyService.ashx文件。

程序B的MyService.ashx代码:

public class MyService : IHttpHandler
 {
 public void ProcessRequest(HttpContext context)
 {
 //获取回调函数名
 string callback = context.Request.QueryString["callback"];
 //json数据
 string json = "{\"name\":\"chopper\",\"sex\":\"man\"}";

 context.Response.ContentType = "application/json";
  //输出:回调函数名(json数据)
  context.Response.Write(callback + "(" + json + ")");
  }

  public bool IsReusable
   {
  get
 {
 return false;
 }
 }
}

程序A的sample代码中的调用:

<script type="text/javascript">
 function addScriptTag(src){
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
  }
  window.onload = function(){
   //调用远程服务
   addScriptTag("http://localhost:20002/MyService.ashx?callback=person");

  }
  //回调函数person
     function person(data) {
  alert(data.name + " is a " + data.sex);
   }
 </script>  

这就完成了一个最基本的JSONP服务调用了

Animation使用

Swiper Animate使用方法

Swiper Animate,是Swiper中文网提供的用于在Swiper内快速制作CSS3动画效果的小插件,适用于Swiper2.x和Swiper3.x 。
此插件不适用于loop模式

  1. 使用Swiper Animate需要先加载swiper.animate.min.js和animate.min.css。code:
    <!DOCTYPE html>
    <html>
    <head>
    ...
    <link rel="stylesheet" href="path/to/swiper.min.css">
    <link rel="stylesheet" href="path/to/animate.min.css">
    

    ...
    <script src="path/to/swiper.min.js"></script>
    <script src="path/to/swiper.animate.min.js"></script>
    

  2. 初始化时隐藏元素并在需要的时刻开始动画。
    code:

  3. 在需要运动的元素上面增加类名 ani ,和其他的类似插件相同,Swiper Animate需要指定几个参数:
    swiper-animate-effect:切换效果,例如 fadeInUp
    swiper-animate-duration:可选,动画持续时间(单位秒),例如 0.5s
    swiper-animate-delay:可选,动画延迟时间(单位秒),例如 0.3s code:
    div class=”swiper-slide”>

    内容



    如果以上这些效果不能满足你的需求,你可以仿照animate.css的格式制作一些其他效果,加到你自己的css文件。其他参数:transition-timing-function

常见兼容性问题(一)

常见兼容性问题

关于各主流浏览器之间的兼容性问题,有时候确实让人头疼,为了提高工作效率,在网上搜集了有关此问题 简单整理了一下,时常来看看
出处:http://www.cnblogs.com/duanhuajian/archive/2012/09/23/2699119.html

ie6.0横向margin加倍

产生因素:块属性、float、有横向margin。
解决方法:display:inline;

2 ie6.0下默认有行高

解决方法:overflow:hidden;或font-size:0;或line-height:xx px;

#####3 在各个浏览器下img有空隙(原因是:回车。)

解决方法:让图片浮动。

4 一个父标签与几个子标签嵌套,父标签不浮动,子标签float,子标签不撑开父的高度。

解决方法:

a 在子标签最后清浮动{

 
}

b 父标签添加{overflow:hidden;}

c 给父标签设置高度

5 Ie6下,不识别最大宽、高度和最小宽高度,意即min-width/height和 Max-width/height在ie6中没效果,

解决方法:

(1):.abc{border:1px blue solid;width:200px;height:200px;}
                  html>body .abc{width:auto;height:auto;min-width:200px;min-        height:200px;}

(2):.abc{width:200px;height:200px;_width:200px;_height:200px;}(因为ie6有一个特征,当定义一个高度时,如果内容超过高度,元素会自动调整高度。)
6 Ie6里面:如li设宽、高,并且li里面的标签浮动,那么li之间会有间距

解决方法:li不设宽、高或者li内的标签不浮动

7 li之间有间距

解决方法:li 设置vertical-align:middle;

8 3像素问题:ie6下,当浮动元素与流动元素并列显示时,他们之间会存在三像素问题。

解决方法:用hack技术, 例如:

   所有浏览器通用 height:100px;

ie6专用_height:100px;

ie7专用*+height:100px; 

ie6/ie7共用*height:100px;
9 当定义行内元素为包含框时,且包含框包含的绝对定位元素以百分比为单位进行定位时,会出现混乱。

解决方法:在行内元素里加入{zoom:1;}

10 当多个浮动元素中间夹杂着HTML注释语句时,如果浮动元素宽度为100%,则在下一行多显示一个上一行最后一个字符。

解决办法:给浮动元素添加display:inline;。

11 opacity 定义元素的不透明度

filter:alpha(opacity=80);/ie支持该属性/

opacity:0.8;/支持css3的浏览器/

12 两个块元素,竖向的margin值不增加,会重叠,其间距为最大margin值。

#####13 优先级:被!important 注明的css属性具有最高优先级(.abc{color:red !important;})。但在ie6中!important具有一个bug:在同一组css属性中,!important不起作用。

14 火狐不识别background-position-y 或background-position-x;
15 ie6 不支持 fixed
/*对于非IE6可以这样写*/
#top{  
position:fixed;  
bottom:0;  
right:20px;  
}  

/*但是IE6是不支持fixed定位的,需要另外重写*/
#top{  
position:fixed;  
_position:absolute;  
top:0;  
right:20px;  
_bottom:auto;  
_top:expression(eval(document.documentElement.scrollTop));
}  

/*使用hack使IE6实现该效果,但这个东东会闪烁,需要以下代码*/
*html{  
background-image:url(about:blank);  
background-attachment:fixed;  
}  

/*使固定在顶部*/
#top{  
_position:absolute;  
_bottom:auto;  
_top:expression(eval(document.documentElement.scrollTop));  
}  

/*固定在底部*/
#top{  
_position:absolute;  
_bottom:auto;  
_top:expression(eval(document.documentElement.scrollTop    +document.documentElement.clientHeight-this.offsetHeight-    (parseInt(this.currentStyle.marginTop)||0)-    (parseInt(this.currentStyle.marginBottom)||0)));  
}  
/*垂直居中*/
#top{
position:fixed;
top:50%;
margin-top:-50px;
_position:absolute;
_top:expression(eval(document.documentElement.scrollTop    +document.documentElement.clientHeight/2)); 
}
16解决 ie6 最大、最小宽高 hack方法
/* 最小宽度 */
.min_width{
min-width:300px;
_width:expression(parseInt(this.clientWidth) < 300 ? "300px" : this.clientWidth);
}

/* 最大宽度 */
.max_width{
       max-width:600px;
       _width:expression(parseInt(this.clientWidth) > 600 ? "600px" :         this.clientWidth);
    }
/* 最小高度 */
.min_height{
   min-height:200px;
   _height:expression(parseInt(this.clientHeight) < 200 ? "200px" :     this.clientHeight);
}

/* 最大高度 */
max_height{
   max-height:400px;
   _height:expression(parseInt(this.clientHeight) > 400 ? "400px" :     this.clientHeight);
}
17 z-index不起作用的 bug

1)ie6下 首先讲讲第一种z-index无论设置多高都不起作用情况。这种情况发生的条件有三个:1、父标签position属性为relative;2、问题标签含有浮动(float)属性。

2)所有浏览器:它只认第一个爸爸
层级的高低不仅要看自己,还要看自己的老爸这个后台是否够硬。用术语具体描述为:
父标签position属性为relative或absolute时,子标签的absolute属性是相对于父标签而言的。而在IE6下,层级的表现有时候不是看子标签的z-index多高,而要看它们的父标签的z-index谁高谁低。

18 ie各个版本hack
/*类内部hack:*/
.header {_width:100px;}            /* IE6专用*/
.header {*+width:100px;}        /* IE7专用*/
.header {*width:100px;}            /* IE6、IE7共用*/
.header {width:100px\0;}        /* IE8、IE9共用*/
.header {width:100px\9;}        /* IE6、IE7、IE8、IE9共用*/
.header {width:330px\9\0;}    /* IE9专用*/

/*选择器Hack:*/
*html .header{}        /*IE6*/ 
*+html .header{}    /*IE7*/ 

JavaScript使用小技巧

JavaScript 小知识点使用

本文是一篇翻译文章,原文信息如下:

  • 原文:<45 useful="" javascript="" tips,="" tricks="" and="" best="" practices="">
  • 作者:
    JavaScript还是很多新手踏入编程世界的第一个语言。既可以用来显示浏览器中的简单提示框,也可以通过nodebot或nodruino来控制机器人。能够编写结构清晰、性能高效的JavaScript代码的开发人员,现如今已成了招聘市场最受追捧的人

    1 用JSON来序列化与反序列化

    var person = {name :’Saad’, age : 26, department : {ID : 15, name : “R&D”} };
    var stringFromPerson = JSON.stringify(person);
    / stringFromPerson 结果为 “{“name”:”Saad”,”age”:26,”department”:{“ID”:15,”name”:”R&D”}}” /
    var personFromString = JSON.parse(stringFromPerson);
    / personFromString 的值与 person 对象相同 /

2 避免使用with()

使用with()可以把变量加入到全局作用域中,因此,如果有其它的同名变量,一来容易混淆,二来值也会被覆盖。

3 传给setInterval()和setTimeout()时使用函数而不是字符串

如果传给setTimeout()和setInterval()一个字符串,他们将会用类似于eval方式进行转换,这肯定会要慢些,因此不要使用:
1 setInterval(‘doSomethingPeriodically()’, 1000);
2 setTimeout(‘doSomethingAfterFiveSeconds()’, 5000);
而是用:
1 setInterval(doSomethingPeriodically, 1000);
2 setTimeout(doSomethingAfterFiveSeconds, 5000);

4 使用switch/case代替一大叠的if/else

其实,switch/case中的case条件,还可以这样写:
function getCategory(age) {
var category = “”;
switch (true) {
case isNaN(age):
category = “not an age”;
break;
case (age >= 50):
category = “Old”;
break;
case (age <= 20):
category = “Baby”;
break;
default:
category = “Young”;
break;
};
return category;
}
getCategory(5); // 将返回 “Baby”

5 HTML字段转换函数

function escapeHTML(text) {  
var replacements= {"<": "&lt;", ">": "&gt;","&": "&amp;", "\"": "&quot;"};                      
return text.replace(/[<>&"]/g, function(character) {  
    return replacements[character];  
}); 

}

6 开发时注意代码结构,上线前检查并压缩JavaScript代码

可以使用JSLint或JSMin等工具来检查并压缩代码。

7 临时存储用于计算和查询的变量

在jQuery选择器中,可以临时存储整个DOM元素。
var navright = document.querySelector(‘#right’);
var navleft = document.querySelector(‘#left’);
var navup = document.querySelector(‘#up’);
var navdown = document.querySelector(‘#down’);

8 通过for-in循环检查对象的属性

下面这样的用法,可以防止迭代的时候进入到对象的原型属性中。
for (var name in object) {
if (object.hasOwnProperty(name)) {
// do something with name
}
}

9 浮点计算的问题

1 0.1 + 0.2 === 0.3 // is false
2 9007199254740992 + 1 // is equal to 9007199254740992
3 9007199254740992 + 2 // is equal to 9007199254740994

为什么呢?因为0.1+0.2等于0.30000000000000004。JavaScript的数字都遵循IEEE 754标准构建,在内部都是64位浮点小数表示,具体可以参见JavaScript中的数字是如何编码的.

可以通过使用toFixed()和toPrecision()来解决这个问题。

10 在条件中使用逻辑与或

1 var foo = 10;
2 foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething();
3 foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();

11 使用length属性截断数组

前面的例子中用length属性清空数组,同样还可用它来截断数组:
1 var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];
2 myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].
与此同时,如果把length属性变大,数组的长度值变会增加,会使用undefined来作为新的元素填充。length是一个可写的属性。
1 myArray.length = 10; // the new array length is 10
2 myArray[myArray.length - 1] ; // undefined

12 获取数组中的最大值和最小值

1 var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
2 var maxInNumbers = Math.max.apply(Math, numbers);
3 var minInNumbers = Math.min.apply(Math, numbers);

13 清空数组

var myArray = [12 , 222 , 1000 ];
myArray.length = 0; // myArray will be equal to [].

14 数组之间追加

1 var array1 = [12 , “foo” , {name “Joe”} , -2458];
2 var array2 = [“Doe” , 555 , 100];
3 Array.prototype.push.apply(array1, array2);
4 / array1 值为 [12 , “foo” , {name “Joe”} , -2458 , “Doe” , 555 , 100] /

15 字符串去空格

Java、C#和PHP等语言都实现了专门的字符串去空格函数,但JavaScript中是没有的,可以通过下面的代码来为String对象函数一个trim函数:
1 String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, “”);};

16 javascript && Jquery 获取各种高度

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高)

alert(document.body.clientWidth); //网页可见区域宽(body)
alert(document.body.clientHeight); //网页可见区域高(body)
alert(document.body.offsetWidth); //网页可见区域宽(body),包括border、margin等
alert(document.body.offsetHeight); //网页可见区域宽(body),包括border、margin等
alert(document.body.scrollWidth); //网页正文全文宽,包括有滚动条时的未见区域
alert(document.body.scrollHeight); //网页正文全文高,包括有滚动条时的未见区域
alert(document.body.scrollTop); //网页被卷去的Top(滚动条)
alert(document.body.scrollLeft); //网页被卷去的Left(滚动条)
alert(window.screenTop); //浏览器距离Top
alert(window.screenLeft); //浏览器距离Left
alert(window.screen.height); //屏幕分辨率的高
alert(window.screen.width); //屏幕分辨率的宽
alert(window.screen.availHeight); //屏幕可用工作区的高
alert(window.screen.availWidth); //屏幕可用工作区的宽

Jquery
alert($(window).height()); //浏览器当前窗口可视区域高度
alert($(document).height()); //浏览器当前窗口文档的高度
alert($(document.body).height());//浏览器当前窗口文档body的高度
alert($(document.body).outerHeight(true));//浏览器当前窗口文档body的总高度 包括border padding margin
alert($(window).width()); //浏览器当前窗口可视区域宽度
alert($(document).width()); //浏览器当前窗口文档对象宽度
alert($(document.body).width()); //浏览器当前窗口文档body的宽度
alert($(document.body).outerWidth(true));//浏览器当前窗口文档body的总宽度 包括border padding margin

深入理解Ajax

深入理解Ajax

1 什么是AJAX ,AJAX原理

AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML)通过在后台与服务器进行少量 数据交

换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分 进行更新。传统的

网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。

原理:XMLHttpRequest

2 使用异步加载获取JS数据至少两种方法?
post, get

3 什么是JSON,JSON的格式

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON 语法是 JavaScript 对象表示 语法的子集。

数据在键值对中

   数据由逗号分隔

   花括号保存对象

   方括号保存数组

除了AJAX还有jsonp可以与后台交互

4 AJAX中的跨域问题:什么是跨域?如何解决跨域问题?

域不一样的,即为跨域,包括(协议,域名,端又号)

解决跨域问题方法:

  • 1.// 指定允许其他域名访问

    header(‘Access-Control-Allow-Origin:*’);

  • 2.使用jsonp

5 AJAX的流程是什么?

  • 1.客户端产生js的事件

  • 2.创建XMLHttpRequest对象 3.对XMLHttpRequest进行配置 4.通过AJAX引擎发送异步请求 5.服务器端接收请

求并且处理请求,返回html或者xml内容 6.XML调用一个callback()处理响应回来的内容 7.页面局部刷新

6 AJAX如何调用JSON数据? xml.responseText

7 AJAX能够处理哪些格式的文件

8 AJAX实现表单验证用户注册流程

  • 用户触发ajax请求,后台接又返回json格式字符串

9 JSON数据的解析方法

* 1.JSON.parse(json)

* 2.new Function(“return ” + json) (); 3.eval(“(”+json+”)”)

10 如何转化成JSON字符串

JSON.stringify(json)

11 说明异步请求的get和post方法的区别

1.使用Get请求时,参数在URL中显示,而使用Post方式,则不会显示出来 

 2.使用Get请求发送数据量小,Post请求发送数据量大

12 列举AJAX的优势

传统的Web应用交互由用户触发一个HTTP请求到服务器,服务器对其进行处理后再返回一个新的 HTHL页到客户端, 每当服务器处理客户端提交的请求时,客户都只能空闲等待,并且哪怕只是一次很小的交互、 只需从服务器端得到很简单的一个数据,都要返回一个完整的HTML页,而用户每次都要浪费时间和带宽去重新 读取整个页面。这个做法浪费了许多带宽,由于每次应用的交互都需要向服务器发送请求,应用的响应时间就 依赖于服务器的响应时间。这导致了用户界面的响应比本地应用慢得多。

与此不同,AJAX应用可以仅向服务器发送并取回必需的数据,它使用SOAP或其它一些基于XML的Web Service接又,并在客户端采用JavaScript处理来自服务器的响应。因为在服务器和浏览器之间交换的数据大量减 少,结果我们就能看到响应更快的应用。同时很多的处理工作可以在发出请求的客户端机器上完成,所以Web 服务器的处理时间也减少了。

13 AJAX中创建请求的兼容性处理

var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new     ActiveXObject("Microsoft.XMLHTTP");

14 对于request.status的http状态码 用于表示网页服务器HTTP响应状态的3位数字代

码。1,2,3,4,5开头的状态码分别代表什么(提示:404页面表示禁止访问等)

1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码。

2xx (成功)表示成功处理了请求的状态代码。

3xx (重定向) 表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。

4xx(请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处理。

5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错

误。 这些错误可能是服务器

15 下列对get和post的区别描述错误的是(C )

A、get比post更常用

B、get发送信息为明文发送,安全性较差

C、get的性能只有post的1/3

D、get传输数据是通过URL进行的

16 如何将js对象转化成JSON字符串( D )
A、JSON.parseInt() B、JSON.parse() C、JSON.string () D、JSON.stringify ()

17 AJAX流程

var xhr = window.XMLHttpRequest ?
new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP") ;
 /*创建 一个AJAX对象*/

xhr.open(type,url);

//请求方式为post时需要加上
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");

xhr.send();

xhr.onreadystatechange = function(){

    if(xhr.readyState === 4 && xhr.status === 200){
        //doSometing

        <!--解析数据-->
        var data = xhr.responseText;

        <!--回调函数-->
        callback(data);
        }
    }

18 AJAX的工作原理

Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化。 并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎自己来做, 只有确定需要 从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。
Ajax其核心有JavaScript、XMLHTTPRequest、DOM对象组成,通过XmlHttpRequest对象来向服务器发异 步请求,从服务器获得数据,然后用JavaScript来操作DOM而更新页面。这其中最关键的一步就是从服务器获 得请求数据。

第一步:创建ajax对象(XMLHttpRequest/ActiveXObject(Microsoft.XMLHttp)) 第二步:判断数据传输方式(GET/POST)

第三步:打开链接 open()

第四步:发送 send() 当ajax对象完成第四步(onreadystatechange)数据接收完成,判断http响应状态(status)200-300之间或

者304(缓存)执行回调函数 注意:检测XMLHttpRequest对象的readyState属性,该属性表示请求/响应过程的当前活动阶段,属

性值如下:

0:未初始化。尚未调用open()方法

1:启动。已经调用open()方法,但尚未调用send()方法 2:发送。已经调用send()方法,但尚未接收到响应

3:接收。已经接收到部分响应数据

4: 完成。已经接收到全部响应数据,而且已经可以在客户端使用了(如果写原生的js ajax请求需要等到
readyState==4的时候再做处理)其他的js库已经做好处理了,放心使用

19 . Jsonp的意义,用法,优点和原理
JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更 好,在更加古老的浏览器中都 可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通 过调用callback的方式回传结果。
JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请 求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
JSONP原理
JSONP的最基本的原理是:动态添加一个是一致的(qq空间就是大量采用这 种方式来实现跨域数据交换的)。JSONP是一种脚本注入(Script Injection)行为,所以有一定的安全隐患。

20 get与post两种方式的优缺点。

get:

get是从服务器上获取数据,post是向服务器传送数据; get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4
中最大量为80KB,IIS5中为100KB;
get安全性非常低,post安全性较高。但是执行效率却比Post方法好; get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在
URL中可以看到; 在做数据查询时,建议用Get方式;

post:

post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属 性所指的URL地址,用户看不到这个过程;
所以:包含机密信息的话,建议用Post数据提交方式;而在做数据添加、修改或删除时,建议用Post方 式。

21 一次完整的HTTP事务是怎样一个过程?

a.域名解析

b.发起TCP的三次握手 c.建立TCP连接后发起http请求 d.服务器端响应http请求,浏览器得到html码 e.浏览器解析html代码,并请求html代码中的资源 f.浏览器对页面进行渲染并呈现给客户

更多详细参考地址:http://www.360doc.com/content/14/0725/20/1073512_397054861.shtml

22 CORS是什么?对于跨域请求,如何将附带凭证(HTTP Cookie及HTTP认证信息) 的请求发送至服务器?

跨域请求一直是网页编程中的一个难题,在过去,绝大多数人都倾向于使用JSONP来解决这一问题。 不过现在,我们可以考虑一下W3C中一项新的特性——CORS(Cross-Origin Resource Sharing)了。CORS是现 代浏览器支持跨域资源请求的一种方式。
解决方法:
当你使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头: Origin,后台(php或者其它接收数据方)进行一系列处理,如果确定接受请求则在返回结果中加入一个响应 头:Access-Control-Allow-Origin;浏览器判断该相应头中是否包含Origin的值,如果有则浏览器会处理响应,我 们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。
更多参考地址:www.cnblogs.com/dojo-lzz/p/4265637.html
http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html

23 浅谈一下如何避免用户多次点击造成的多次请求。

我们在访问有的网站,输入表单完成以后,单击提交按钮进行提交以后,提交按钮就会变为灰色,
用户不能再单击第二次,直到重新加载页面或者跳转。这样,可以一定程度上防止用户重复提交导致应用程序
上逻辑错误。

还有很多其他的方式进行防止重复点击提交,如
1> 定义标志位: 点击触发请求后,标志位为false量;请求(或者包括请求后具体的业务流程处理)后,标志位为true
量。通过标志位来判断用户点击是否具备应有的响应。 2> 卸载及重载绑定事件:
点击触发请求后,卸载点击事件;请求(或者包括请求后具体的业务流程
处理)后,重新载入绑定事

件。
3> 替换(移除)按钮DOM 点击触发请求后,将按钮DOM对象替换掉(或者将之移除),自然而然此时不在具备点击事件;请求
(或者包括请求后具体的业务流程处理)后,给新的按钮DOM定义点击事件。 更多讲解参考:http://www.cnblogs.com/jinguangguo/archive/2013/05/20/3086925.html

24 异步加载的方式有哪些?

(1)defer,只支持 IE

(2)async:

(3)创建 script,插入到 DOM 中,加载完毕后 callBack

bootstrap轮播图片的设计

bootstrap轮播图片的设计

http://img1.sc115.com/uploads/sc/jpg/HD/2/45.jpg

一个轮播图片主要包括三个部分:

  • ☑ 轮播的图片

  • ☑ 轮播图片的计数器

  • ☑ 轮播图片的控制器

复杂一点的轮播图片,每个轮播区会带有对应的标题和描述内容。那么在 Bootstrap 框架中,轮播图是如何设计的呢?

第一步:设计轮播图片的容器。在 Bootstrap 框架中采用 carousel 样式,并且给这个容器定义一个 ID 值,方

便后面采用 data 属性来声明触发。

第二步:设计轮播图片计数器。在容器 div.carousel 的内部添加轮播图片计算器,采用 carousel-

indicators 样式,其主要功能是显示当前图片的播放顺序(有几张图片就放置几个li),一般采用有顺列表来制作:

<div id="slidershow" class="carousel">
<!-- 设置图片轮播的顺序 -->
<ol class="carousel-indicators">
    <li class="active">1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    ...
</ol>
</div>

在 Bootstrap 框架中,轮播图片计数器,都是以圆点向大家呈现,其具体样式如下:

/*bootstrap.css文件第5835行~第5863行*/
.carousel-indicators {
position: absolute; /*整个计数区域绝对定位*/
bottom: 10px; /*距容器carousel底部10px*/
z-index: 15; /*设置其在Z轴的层级*/
/*让整个计数区水平居中*/
left: 50%;
width: 60%;
padding-left: 0;
margin-left: -30%;
text-align: center;
list-style: none;
}
.carousel-indicators li {
display: inline-block;
width: 10px;
height: 10px;
margin: 1px;
text-indent: -999px;
cursor: pointer;
background-color: #000 \9;
background-color: rgba(0, 0, 0, 0);
border: 1px solid #fff;
border-radius: 10px;
}
/*设置当前状态样式*/
.carousel-indicators .active {
width: 12px;
height: 12px;
margin: 0;
background-color: #fff;
}

第三步:设计轮播图片播放区。轮播图整个效果中,播放区是最关键的一个区域,这个区域主要用来放置需要轮播的图片。这个区域使用 carousel-inner 样式来控制,而且其同样放置在 carousel 容器内,并且通过 item 容器来放置每张轮播的图片:

<div id="slidershow" class="carousel">
    <!-- 设置图片轮播的顺序 -->
       <ol class="carousel-indicators">
        <li class="active">1</li>
            …
        </ol>
    <!-- 设置轮播图片 -->
    <div class="carousel-inner">
        <div class="item active">
            <a href="##"><img src="ll580x145.jpg" alt=""></a>
        </div>
           <div class="item">
            <a href="##"><img src="580145.jpg" alt=""></a>
        </div>
                …
        <div class="item">
            <a href="##"><img src="580145.jpg" alt=""></a>
        </div>
    </div>
</div>

其主要通过 carousel-inner 来控制其样式呈现。

第四步:设计轮播图片控制器。很多时候轮播图片还具有一个向前播放和向后播放的控制器。在 Carousel 中通过 carousel-control 样式配合 left 和 right 来实现。其中left表示向前播放,right表示向后播放。其同样放在carousel容器内:

 <div id="slidershow" class="carousel">
    <!-- 设置图片轮播的顺序 -->
    <ol class="carousel-indicators">
       …
    </ol>
    <!-- 设置轮播图片 -->
    <div class="carousel-inner">
        …
    </div>
    <!-- 设置轮播图片控制器 -->
       <a class="left carousel-control" href="" >
        <span class="glyphicon glyphicon-chevron-left"></span>
        </a>
    <a class="right carousel-control" href="">
        <span class="glyphicon glyphicon-chevron-right"></span>
    </a>
</div>

通过两个 a 链接然后在内部定义要显示的小图标,一个是向前,一个是向后。
这两个图标都显示在图片容器的上面(z-index的值大于carousel-inner的)。

本文转载自 http://mp.weixin.qq.com/s?__biz=MjM5MDA2MTI1MA==&mid=2649084355&idx=1&sn=b8f8542961fb22ec79f08d11712c6efb&chksm=be5bf66e892c7f7805bc5798806a4b15e9a21de68a32996b34a37e0ef8b63ff574cef09ae2a2&mpshare=1&scene=23&srcid=1120rw2qKTy789hDAF6IAO5R#rd

正则表达式应用——实例应用

正则表达式应用——实例应用

1.验证用户名和密码:(”^[a-zA-Z]\w{5,15}$”)正确格式:”[A-Z][a-z]_[0-9]”组成,并且第一个字必须为字母6~16位;

2.验证电话号码:(”^(\d{3,4}-)\d{7,8}$”)正确格式:xxx/xxxx-xxxxxxx/xxxxxxxx;

3.验证手机号码:”^1[3|4|5|7|8][0-9]\d{8}$”;

4.验证身份证号(15位或18位数字):”^\d{14}[[0-9],0-9xX]”;

5.验证Email地址:(“^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$”);

6.只能输入由数字和26个英文字母组成的字符串:(“^[A-Za-z0-9]+$”) ;

7.整数或者小数:^[0-9]+([.][0-9]+){0,1}$

8.只能输入数字:”^[0-9]*$”。

9.只能输入n位的数字:”^\d{n}$”。

10.只能输入至少n位的数字:”^\d{n,}$”。

11.只能输入m~n位的数字:”^\d{m,n}$”。

12.只能输入零和非零开头的数字:”^(0|[1-9][0-9]*)$”。

13.只能输入有两位小数的正实数:”^[0-9]+(.[0-9]{2})?$”。

14.只能输入有1~3位小数的正实数:”^[0-9]+(.[0-9]{1,3})?$”。

15.只能输入非零的正整数:”^+?[1-9][0-9]*$”。

16.只能输入非零的负整数:”^-[1-9][0-9]*$”。

17.只能输入长度为3的字符:”^.{3}$”。

18.只能输入由26个英文字母组成的字符串:”^[A-Za-z]+$”。

19.只能输入由26个大写英文字母组成的字符串:”^[A-Z]+$”。

20.只能输入由26个小写英文字母组成的字符串:”^[a-z]+$”。

21.验证是否含有^%&’,;=?$\”等字符:”[%&’,;=?$\^]+”。

22.只能输入汉字:”^[\u4e00-\u9fa5]{0,}$”。

23.验证URL:”^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$”。

24.验证一年的12个月:”^(0?[1-9]|1[0-2])$”正确格式为:”01”~”09”和”10”~”12”。

25.验证一个月的31天:”^((0?[1-9])|((1|2)[0-9])|30|31)$”正确格式为;”01”~”09”、”10”~”29”和“30”~“31”。

26.获取日期正则表达式:\d{4}[年|-|.]\d{\1-\12}[月|-|.]\d{\1-\31}日? 评注:可用来匹配大多数年月日信息。

27.匹配双字节字符(包括汉字在内):[^\x00-\xff] 评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

28.匹配空白行的正则表达式:\n\s*\r 评注:可以用来删除空白行

29.匹配HTML标记的正则表达式:<(\S?)[^>]>.?</>|<.? /> 评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力

31.匹配首尾空白字符的正则表达式:^\s|\s$ 评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式

33.匹配网址URL的正则表达式:[a-zA-z]+://[^\s]* 评注:网上流传的版本功能很有限,上面这个基本可以满足需求

35.匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 评注:表单验证时很实用

37.匹配腾讯QQ号:[1-9][0-9]{4,} 评注:腾讯QQ号从10 000 开始

39.匹配中国邮政编码:[1-9]\d{5}(?!\d) 评注:中国邮政编码为6位数字

41.匹配ip地址:([1-9]{1,3}.){3}[1-9]。 评注:提取ip地址时有用

43.匹配MAC地址:([A-Fa-f0-9]{2}\:){5}[A-Fa-f0-9]

npm

浅聊:Yarn vs npm

原文链接 https://www.sitepoint.com/yarn-vs-npm/?utm_source=javascriptweekly&utm_medium=email

译文 http://www.zcfy.cc/article/yarn-vs-npm-everything-you-need-to-know-1484.html

Yarn 是 Facebook, Google, Exponent 和 Tilde 开发的一款新的 JavaScript 包管理工具。就像我们可以从官方文档了解那样,它的目的是解决这些团队使用 npm 面临的少数问题,即:

  • 安装的时候无法保证速度/一致性
  • 安全问题,因为 npm 安装时允许运行代码

但请不要惊慌!它并没有试图完全取代 npm。Yarn 同样是一个从 npm 注册源获取模块的新的 CLI 客户端。注册的方式不会有任何变化 —— 你同样可以正常获取与发布包。

是否每个人现在都要跳上 Yarn 这辆被大肆宣传的列车?又或者你根本没机会碰到 npm 的这些问题。本篇文章将会比较 npm 与 Yarn,最终你可以决定哪款更适合你。

Yarn vs npm: 功能差异

乍一看 Yarn 与 npm 很类似,但通过引擎的对比就能察觉 Yarn 的不同。

yarn.lock 文件

npm 和 Yarn 都使用 package.json 来跟踪项目的依赖,版本号并非一直准确,因为你可以定义版本号范围,这样你可以选择一个主版本和次要版本的包,但让 npm 安装最新的补丁也许可以修改一些 bug。

理想状态下使用语义化版本发布补丁不会包含大的变化,但不幸的是这必非真理。npm 的这种策略可能导致两台拥有相同 package.json 文件的机子安装了不同版本的包,这可能导致一些错误。

为了避免包版本的错误匹配,一个确定的安装版本被固定在一个锁文件中。每次模块被添加时,Yarn 就会创建(或更新)yarn.lock 文件,这样你就可以保证其它机子也安装相同版本的包,同时包含了 package.json 中定义的一系列允许的版本。

在 npm 中同样可以使用 npm shrinkwrap 命令来生成一个锁文件,这样在使用 npm install 时会在读取 package.json 前先读取这个文件,就像 Yarn 会先读取yarn.lock 一样。这里的区别是 Yarn 总会自动更新 yarn.lock,而 npm 需要你重新操作。

并行安装

每当 npm 或 Yarn 需要安装一个包时,它会进行一系列的任务。在 npm 中这些任务是按包的顺序一个个执行,这意味着必须等待上一个包被完整安装才会进入下一个;Yarn 则并行的执行这些任务,提高了性能。

为了比较,我在没有使用 shrinkwrap/yarn.lock 的方式以及清理了缓存下使用 npm 与 Yarn 安装 express,总共安装了 42 个依赖。

  • npm: 9 s
  • Yarn: 1.37 s

我无法相信自己的眼睛,所以重复以上步骤,但得到相同结果。接着我安装 gulp 进行测试,总共安装了 195 个依赖。

  • npm: 11 s
  • Yarn: 7.81 s

似乎根据所需要安装的包的数量而有所不同,但 Yarn 依旧比较快。

清晰的输出

npm 默认情况下非常冗余,例如使用 npm install 时它会递归列出所有安装的信息;而 Yarn 则一点也不冗余,当可以使用其它命令时,它适当的使用 emojis 表情来减少信息(Windows 除外)。

Yarn vs npm: CLI 的差异

除了一些功能差异,Yarn 命令也存在一些区别。例如移除或修改了一些 npm 命令以及添加了几个有趣的命令。

yarn global

不像 npm 添加 -g--global 可以进行全局安装,Yarn 使用的是 global 前缀。不过与 npm 类似,项目依赖不推荐全局安装。

global 前缀只能用于 yarn add, yarn bin`, yarn lsyarn remove,除yarn add `外,这些命令都和 npm 等效。

yarn install

npm install 命令会根据 package.json 安装依赖以及允许你添加新的模块;yarn install 仅会按 yarn.lockpackage.json 里面的依赖顺序来安装模块。

yarn add [–dev]

npm install 类似,yarn add 允许你添加与安装模块,就像命令的名称一样,添加依赖意味着也会算定将依赖写入 package.json,类似 npm--save 参数;Yar 的--dev `参数则是添加开发依赖,类似 npm 的 –save-dev 参数。

yarn licenses [ls|generate-disclaimer]

npm 没有类似命令来方便编写自己的包。 yarn licenses ls 列出所有已安装包的许可协议。 yarn licenses generate-disclaimer 生成包含已安装包许可协议的免责声明。某些协议要求使用者必须在项目中包含该协议,这时候该命令将变得非常好用。

yarn why

该命令会查找依赖关系并找出为什么会将某些包安装在你的项目中。也许你明确为什么添加,也许它只是你安装包中的一个依赖,yarn why 可以帮你弄找出。

yarn upgrade

该命令会根据符合 package.json 设定的规则而不是 yarn.lock 定义的确切版本来将包更新到最新版本。如果想用 npm 来实现相同目的,可以这样执行:

rm -rf node_modules
npm install

不要将该命令与 npm update 混淆,它指的是更新到自己的最新版。

yarn generate-lock-entry

yarn generate-lock-entry 会基于 package.json 设置的依赖生成 yarn.lock 文件,该命令与 npm shrinkwrap 类似,但应该小心使用,因为通过 yarn addyarn upgrade 命令添加或更新依赖时会自动更新生成该锁文件。

稳定性与可靠性

Yarn 被炒得这么火热会不会有问题?它正式发布当天就收到很多问题反馈,但官方处理问题的速度极快。这些表明社区正努力开发并修复bug。查看问题反馈的数量和类型可以发现 Yarn 在大多数用户的机子上表现的很稳定,但可能个别机子会有问题。

请注意虽然一个包管理器可能对你的项目非常重要,但它仅仅只是个工具,如果出了状况,恢复包不会困难,也并非要回归 npm。

未来

也许你了解 Node.js 与 io.js 之间的历史。简单来说:io.js 是 Node.js 一些核心开发者因为项目管理上的分歧而独立出来创建的分支。不同的是,io.js 选择了开放式管理,在不到一年的时间时,两支团队达成协议,io.js 被合并回 Node.js,无论对错,它为 Node.js 带来了相当多不错的功能。

我看到 npm 与 Yarn 和它们有着类似的模式,不过 Yarn 不是分支,它解决了 npm 的一些缺陷。如果 npm 从中学到东西并邀请 Facebook,Google 或其它 Yarn 的贡献者们来一起提升 npm 不是很酷吗?虽然言之过早,但我期待它会发生。

无论哪种结果,Yarn 前途一片光明。社区得到别人对新工具的赞扬后似乎很兴奋,不幸的是,社区并没有提供路线图,所以我不确定 Yarn 是否为我们准备了其它惊喜。

结论

相比 npm 的默认配置,Yarn 获得不少赞同。我们可以方便生成锁文件,安装包时非常迅速并且他们会自动添加进 package.json,同时安装与使用 Yarn 的影响也很小,你可以直接在一个项目上尝试看它是否可以工作,这使得 Yarn 可以完美替代 npm。

我绝对推荐在一个项目中尽早使用 Yarn,如果你对安装和使用新软件持谨慎态度,可以等待几个月。毕竟 npm 久经考验,它在软件开发领域也有存在的价值。

使用你正确等待 npm 完成包的安装,也许这是阅读迁移指南的最佳时刻 ;)

你怎么想呢?你是否已经在使用 Yarn?你是否将要尝试?或者这只是一个已经支离破碎的生态系统的进一步破碎?请在下面评论区留下你的观点。

  • Copyrights © 2015-2021 魏姣
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信