css精确控制表格列宽

table-layout: 默认值为 auto,即自动表格布局算法,列宽会根据其内容进行调整,即使我们显式指定了 width,也只是起到类似提示的作用。

将其设为 fixed,要明显可控一些。设置的宽会直接起作用,溢出行为 text-overflow 也表现正常。

使用时需要为表格元素指定一个宽度(哪怕是100%)。

table {
    table-layout: fixed;
    width:100%;
}

要让 text-overflow:ellipsis 发挥效用。还需要为那一列指定宽度。

demo地址:
http://dabblet.com/gist/7979af102a991cecfcdf

iOS下webview中JS调用原生OC

因项目需要,需要在页面中传递值给ios客户端。经过联调最后使用 JavaScriptCore 这种方法完成。

过程中开始使用 WebViewJavascriptBridge 这种方法,最后出现os只能调用本地的页面时才生效,在群友推荐下,改用JavaScriptCore这种方法。经过各种调试才算调通。

JavaScriptCore是webkit的一个重要组成部分,主要是对JS进行解析和提供执行环境。iOS7后苹果在iPhone平台推出,极大的方便了我们对js的操作。我们可以脱离webview直接运行我们的js,推荐使用

先定义通讯类js方法,等加载好后。再进行业务js的执行。
定义:

function testResponse(obj){
    native.testResponse(obj);
}

调用:

    // 调用oc方法传递信息
    testResponse(iosSdkAuthResult);

参考文章:
iOS下JS与原生OC互相调用(总结)
JavaScriptCore 使用

gulp-rev-append 小记

使用gulp-rev-append给页面的引用添加版本号,清除页面引用缓存。简单配置如下:

var gulp = require('gulp');
var rev = require('gulp-rev-append');

gulp.task('rev', function() {
 gulp.src('./index.html')
 .pipe(rev())
 .pipe(gulp.dest('./dest'));
});

针对相对路径使用,对于简单的页面来说没问题,但使用后端模板文件后路径变化时就不太适用了。

这是也只用使用 gulp-rev-collector 了,复杂度提高了。

常用es6特性学习

ES6给我们提供了许多的新语法和代码特性来提高javascript的体验。

定义函数

我们先来看一个基本的新特性,在javascript中,定义函数需要关键字function,但是在es6中,还有更先进的写法,我们来看:

es6写法:

var human = {
    breathe(name) {   //不需要function也能定义breathe函数。
        console.log(name + ' is breathing...');
    }
};
human.breathe('jarson');   //输出 ‘jarson is breathing...’

转成以前的js代码:

var human = {
    breathe: function(name) {
        console.log(name + 'is breathing...');
    }
};
human.breathe('jarson');

创建类

我们知道,javascript不像java是面向对象编程的语言,而只可以说是基于对象编程的语言。所以在js中,我们通常都是用function和prototype来模拟类这个概念。

但是现在有了es6,我们可以像java那样‘明目张胆’的创建一个类了:

class Human {
    // 构造方法,实例化的时候将会被调用,如果不指定,那么会有一个不带参数的默认构造函数。
    constructor(name) {
    	this.name = name;
    }
    // 是原型对象上的属性
    breathe() {
        console.log(this.name + " is breathing");
    }
}
var man = new Human("jarson");
man.breathe();    // jarson is breathing

man.hasOwnProperty("name"); // true
man.__proto__.hasOwnProperty('breathe'); // true

hasOwnProperty() 方法用来判断某个对象是否含有指定的自身属性。和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
__proto__属性的值就是它的原型。

上面代码转为js格式:

function Human(name) {
    this.name = name;
    this.breathe = function() {
        console.log(this.name + ' is breathing');
    }
}
var man = new Human('jarson');
man.breathe();    //jarson is breathing

所以我们看到,我们可以像java那样语义化的去创建一个类。另外,js中的继承父类,需要用prototype来实现。那么在es6中,又有什么新的方法来实现类的继承呢?

继续看:

假如我们要创建一个Man类继承上面的Human类,es6代码:

class Man extends Human {
    constructor(name, sex) {
        // 子类必须要在constructor中指定 super 方法,否则在新建实例的时候会报错
        // 如果没有置顶consructor,默认带 super 方法的constructor将会被添加
        super(name); // 即调用父类的构造函数
        this.sex = sex;
    }
    info(){
        console.log(this.name + ' is ' + this.sex);
    }
}
var xx = new Man('jarson', 'boy');
xx.breathe();   // jarson is breathing
xx.info();   // jarson is boy

console.log(xx instanceof Human); // true
console.log(xx instanceof Man); // true

代码很简单,不作赘述,可以使用文章里提到的在线工具去试试效果就能明白了。需要注意的是: super() 是父类的构造函数。

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

let与const

在我看来,在es6新特性中,在定义变量的时候统统使用 let 来代替 var 就好了, const 则很直观,用来定义常量,即无法被更改值的变量。

for (let i=0;i<2;i++) {
    console.log(i);  //输出: 0,1
}

箭头函数

ES6中新增的箭头操作符 => 简化了函数的书写。操作符左边为输入的参数,而右边则是进行的操作以及返回的值,这样的写法可以为我们减少大量的代码,看下面的实例:

let arr = [6, 8, 10, 20, 15, 9];
arr.forEach((item, i) => console.log(item, i));
let newArr = arr.filter((item) => (item<10));
console.log(newArr); //[6, 8, 9];

上面的 (item, i) 就是参数,后面的 console.log(item, i) 就是回到函数要执行的操作逻辑。

上面代码转为js格式:

var arr = [6, 8, 10, 20, 15, 9];
arr.forEach(function(item, i) {
	return console.log(item, i);
});
var newArr = arr.filter(function(item) {
    return (item < 10);
});
console.log(newArr);

字符串模版

ES6中允许使用反引号 ` 来创建字符串,此种方法创建的字符串里面可以包含由美元符号加花括号包裹的变量${vraible}。看一下实例就会明白了:

//产生一个随机数
let num = Math.random();
//将这个数字输出到console
console.log(`your num is ${num}`);

 

摘录自:
http://www.open-open.com/lib/view/open1462951574598.html
https://segmentfault.com/a/1190000002904199

在JavaScript中创建命名空间的几种写法(转)

在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺序来的,可以看看下面的例子:
var sayHello = function() {
  return 'Hello var';
};

function sayHello(name) {
  return 'Hello function';
};

sayHello();
最终的输出为
> "Hello var"

为什么会这样,根据 StackOverFlow 的解释,实际上JavaScript的是按如下顺序解析的。

function sayHello(name) {
  return 'Hello function';
};

var sayHello = function() {
  return 'Hello var';
};

sayHello();
不带var的function声明被提前解析了,因此现代的JS写法建议你始终使用前置var声明所有变量;
避免全局变量名冲突的最好办法还是创建命名空间,下面是在JS中合建命名空间的几种常用方法。
通过函数(function)创建
这是一种比较常见的写法,通过声明一个function实现,函数里设置初始变量,公共方法写入prototype,如:
var NameSpace = window.NameSpace || {};
/*
Function
*/
NameSpace.Hello = function() {
  this.name = 'world';
};
NameSpace.Hello.prototype.sayHello = function(_name) {
  return 'Hello ' + (_name || this.name);
};
var hello = new NameSpace.Hello();
hello.sayHello();
这种写法比较冗长,不利于压缩代码(jQuery使用fn代替prototype),而且调用前需要先实例化(new)。使用Object写成JSON形式可以写得紧凑些:
通过JSON对象创建Object
/*
Object
*/
var NameSpace = window.NameSpace || {};
NameSpace.Hello = {
    name: 'world'
  , sayHello: function(_name) {
    return 'Hello ' + (_name || this.name);
  }
};
调用
NameSpace.Hello.sayHello('JS');
> Hello JS;
这种写法比较紧凑,缺点是所有变量都必须声明为公有(public)的,导致所有对这些变量的引用都需要加this指示作用域,写法也略有冗余。

通过闭包(Closure)和Object实现

在闭包中声明好所有变量和方法,并通过一个JSON Object返回公有接口:
var NameSpace = window.NameSpace || {};
NameSpace.Hello = (function() {
  //待返回的公有对象
  var self = {};
  //私有变量或方法
  var name = 'world';
  //公有方法或变量
  self.sayHello = function(_name) {
    return 'Hello ' + (_name || name);
  };
  //返回的公有对象
  return self;
}());
Object和闭包的改进型写法
上个例子在内部对公有方法的调用也需要添加self,如:self.sayHello(); 这里可以最后再返回所有公有接口(方法/变量)的JSON对象。
var NameSpace = window.NameSpace || {};
NameSpace.Hello = (function() {
  var name = 'world';
  var sayHello = function(_name) {
    return 'Hello ' + (_name || name);
  };
  return {
    sayHello: sayHello
  };
}());
Function的简洁写法
这是一种比较简洁的实现,结构紧凑,通过function实例,且调用时无需实例化(new),方案来自stackoverflow
var NameSpace = window.NameSpace || {};
NameSpace.Hello = new function() {
  var self = this;
  var name = 'world';
  self.sayHello = function(_name) {
    return 'Hello ' + (_name || name);
  };
};

调用

NameSpace.Hello.sayHello();
我喜欢的写法
var yourNamespace = {

    foo: function() {
    },

    bar: function() {
    }
};

...

yourNamespace.foo();

转自:http://ourjs.com/detail/538d8d024929582e6200000c

webpack基本配置

var webpack = require('webpack')
module.exports = {
    entry: {
        index: './src/app.js'
    },
    output: {
        path: './dist/',
        filename: '[name].js',
        publicPath: '/dist'
    },
    scripts: {
      "build": "webpack",
      "dev": "webpack-dev-server --devtool eval --progress --colors --content-base build"
    },
    module: {
        loaders: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel',
            query: {
                presets: ['es2015', 'stage-0', 'react']
            }
        }]
    }
}

dev里各属性值的意思是:

  1. webpack-dev-server: 在 localhost:8080 建立一个 Web 服务器
  2. --devtool eval:为你的代码创建源地址。当有任何报错的时候可以让你更加精确地定位到文件和行号
  3. --progress: 显示合并代码进度
  4. --colors: 在命令行中显示颜色
  5. --content-base build:指向设置的输出目录

注:
publicPath: ‘/dist’
// webpack-dev-server 启动目录是 `/`, `/dist` 目录是打包的目标目录相对于启动目录的路径

webpack-dev-server 还提供了自动刷新功能,有两种模式。

Iframe 模式

修改访问的路径: http://localhost:8080/index.html -> http://localhost:8080/webpack-dev-server/index.html 。这个时候每次修改代码,打包完成过后都会自动刷新页面。

不需要额外配置,只用修改路径
应用被嵌入了一个 iframe 内部,页面顶部可以展示打包进度信息
因为 iframe 的关系,如果应用有多个页面,无法看到当前应用的 url 信息

inline 模式

启动 webpack-dev-server 的时候添加 –inline 参数

需要添加 –inline 配置参数
没有顶部信息提示条,提示信息在控制台中展现

参考:
React+Webpack快速上手指南
精益react-webpack

querySelector和querySelectorAll的功能及区别

HTML5向Web API新引入了document.querySelector以及document.querySelectorAll两个方法用来更方便地从DOM选取元素,功能类似于jQuery的选择器。这使得在编写原生JavaScript代码时方便了许多。

用法:

两个方法使用差不多的语法,都是接收一个字符串参数,这个参数需要是合法的CSS选择语法。

element = document.querySelector('selectors');
elementList = document.querySelectorAll('selectors');

其中参数selectors 可以包含多个CSS选择器,用逗号隔开。

element = document.querySelector('selector1,selector2,...');
elementList = document.querySelectorAll('selector1,selector2,...');

使用这两个方法无法查找带伪类状态的元素,比如querySelector(‘:hover’)不会得到预期结果。

querySelector

该方法返回满足条件的单个元素。按照深度优先和先序遍历的原则使用参数提供的CSS选择器在DOM进行查找,返回第一个满足条件的元素。

querySelectorAll

该方法返回所有满足条件的元素,结果是个nodeList集合。查找规则与前面所述一样。

摘自:http://www.cnblogs.com/Wayou/p/html5_web_api_queryselector.html#undefined

获取触摸事件坐标

	function findCoordinates(e) {
		// 如果需要用 pageX/Y 代替 clinetX/Y
		var x,y;
		if(e.changedTouches){
			x = e.changedTouches[0].clientX;
			y = e.changedTouches[0].clientY;
		}else{
			x = e.clientX;
			y = e.clientY;
		}
		console.log(e);
		$('#test').text("x:"+x+",y:"+y);
		return [x,y];
	}
 
    var el = document.getElementsByClassName('content')[0];
    console.log(el);
 
    el.addEventListener('touchstart', findCoordinates, false);

触摸事件对象有事件类型、时间目标对象、可以阻止默认行为。

其中 touchList 数组包含了每个触摸点的信息。
changedTouches 数组中第一个对象就是导致事件触发的那个触摸点对象。

clientX/Y 和 pageX/Y 的区别是,前者相对于视觉视口的左上角,后者相对于布局视口的左上角。

注:
关于视口的介绍

DPI、DPR、屏幕尺寸等释义

物理分辨率 & 设备分辨率 (Device resolution)
单位:
像素密度 DPI ( Dots per inch ),单位像素/尺寸。是打印机、鼠标等设备分辨率的单位。
 
一平方英寸面积内像素的多少。dpi越小,扫描的清晰度越低,由于受网络传输速度的影响,web上使用的图片都是72dpi。
 
冲洗照片不能使用这个参数,必须是300dpi或者更高350dpi。
 
 
屏幕尺寸:
是指屏幕对角线的尺寸,一般用英寸来表示。1英寸=2.54厘米
 
设备像素比 DPR( devicePixelRatio ):
提供了设备像素个数和理想视口的比。
浏览器厂商决定了设备的理想视口,DPR也由他们决定,单位是dppx。
 
dppx 每一个像素的点数。一英寸对应了css中的96像素,1dppx等于96dpi。
 
resolution 设备的分辨率,如:96dpi, 300dpi
 
设备像素dp(device pixels):
ppi就是设备像素dp(device pixels)的单位。
 
ppi(pixels per inch)表示每英寸所拥有的像素(pixel)数目,数值越高,代表屏幕能以更高的密度显示图像。
计算公式:ppi=像素数量/物理尺寸(英寸数)
 
 
注:
写代码的时候只要关注dpr就可以了,网页的视口的大小是设备分辨率/dpr

修改swiper 2.7.6版本在ie8下点击后停止自动切换的问题

前文“Swiper 循环切换回调实例”中介绍过一些用法。
Swiper 是个优秀的滑动插件插件,有两个版本。3.x版本兼容高版本浏览器 chrome、ie9+ (推测),2.x版本兼容ie8等。
目前2.x已停止维护了,最新版本为 2.7.6.

问题描述:由于要兼容ie8故采用2.7.6版本。测试发现ie8下点击后停止自动切换的问题,chrome正常。
分析:
插件根据这个值 autoplayDisableOnInteraction 来决定用户操作后是否自动切换。在代码中找到,

            if (internal && !params.autoplayDisableOnInteraction) {
                _this.wrapperTransitionEnd(function () {
                    autoplay();
                });
            }

发现能正确执行到if条件中。但ie8下没有执行到autoplay(),继续分析_this.wrapperTransitionEnd,是由ie8不支持 transitionend 事件导致的。修改如下:

    _this.stopAutoplay = function (internal) {
        if (_this.support.transitions) {
            if (!autoplayTimeoutId) return;
            if (autoplayTimeoutId) clearTimeout(autoplayTimeoutId);
            autoplayTimeoutId = undefined;
            if (internal && !params.autoplayDisableOnInteraction) {
                _this.wrapperTransitionEnd(function () {
                    autoplay();
                });
            }
            _this.callPlugins('onAutoplayStop');
            if (params.onAutoplayStop) _this.fireCallback(params.onAutoplayStop, _this);
        }
        else {
            if (autoplayIntervalId) clearInterval(autoplayIntervalId);
            autoplayIntervalId = undefined;
            if (internal && !params.autoplayDisableOnInteraction) {
                _this.startAutoplay();
            }
            _this.callPlugins('onAutoplayStop');
            if (params.onAutoplayStop) _this.fireCallback(params.onAutoplayStop, _this);
        }
    };

swiper-2-7-7