html 5

说到存储,你可能会想到这是服务器端的一种设置。
服务器端的存储介质大体上分为4种:
cache:缓存,它可以让从数据库、磁盘上输出的东西/数据放置在缓存里,从而减少数据库或是磁盘的读取与写入(IO)操作; 磁盘文件:如,我们常常会将图片、视频等文件存放在磁盘上; 数据库:mySql\mongoDB…关系\非关系数据库; 内存:通常放置频繁要使用到的东西,能够提高读取效率;缓存(cache)也是存放在内存里的;

HTML的存储-cookies

在HTML5出生之前,通常在浏览器(客户端)使用cookies来存储客户端的内容;
cookies的特点:
每次的http请求头中,都会带有cookies——缺点; 每个域名只能存储4K大小的cookies; 主域名污染:如果我们使用cookies存储主域名的东西,那么子域名下得Http请求都会带上主域名的东西;
如果关联上网络,那么将带来安全问题。
所以,通常我们会使用cookies用在如购物车、身份验证等问题上。
下面,我们来看一下百度首页的cookies在浏览器端的一个存储形态:
如图:
这里写图片描述
HTTP这一列,如果在setCookie的时候,这里就会打钩,这与HTTPOnly相关。< 喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KCjxwPkhUVFBPbmx5o7o8L3A+Cgo8cD7I57n7sNFIVFRQT25secno1sPOqnRydWUsxMfDtGNvb2tpZXPWu8TcsbtzZXJ2ZXK3/s7xxve2y8C0tsHIobvyysfQ3rjEo6y/zbuntsvDu9PQyKjP3r340NC2wcihus3Q3rjEoaPA/cjno6zO0sPH1Nq9+NDQye233dHp1qS1xMqxuvKjrL7Nv8nS1Mq508PV4rj2oaM8L3A+Cgo8cD5TZWN1cmWjutPrsLLIq8/gudijrMjnufvJ6NbDwcujrMTHw7TH68fz1rvE3MrHwLTX1EhUVFC808Pcx+vH86GjPC9wPgoKCgo8aDMgaWQ9"html的存储-userdata">HTML的存储-UserData 只有IE支持,有微软提供API,但不符合W3C标准; 存储在XML文件中;

HTML5的存储

针对以上问题,HTML5的出现,需要解决以下问题:
解决4K的大小问题; 解决请求头常带存储信息的问题; 解决关系型存储的问题; 跨浏览器平台问题;

HTML5存储形式

本地存储——localstorage \sessionstorage 离线缓存——application cache IndexedDB、Web SQL

本地存储

API:
localstorage 、sessionstorage
存储形式:
key–>value
过期时间:
localstorage:永久存储,永不失效,除非手动删除 
sessionstorage:重新打开页面,或是关闭浏览器,sessionstorage才会消失;
存储大小: 
每个域名能存5M;
支持情况:
IE8+,safari3.2+,chrome,firefox等主流浏览器都支持;
使用方法——localstorage\sessionstorage
主要涉及到5个方法:
getItem:获取localstorage\sessionstorage setItem:设置localstorage\sessionstorage removeItem:移除localstorage\sessionstorage key:获取某一个位置上的key值,按值从0开始索引; clear:全部清除localstorage\sessionstorage
例如:我们打开www.baidu.com
在控制台Console输出面板,输入:
localStorage.setItem("test1","test"); 
那么在Resources面板的Local Storage下,将出现Key=test1,value=test的记录
localStorage.getItem("test1"); //输出test
localStorage.key(0);//输出BDSUGSTORED
sessionstorage的API与localstorage一样,但是你要注意一点:
sessionStorage需要在浏览器关闭或是重新打开页面,才会消失;

本地存储可以存储什么?

数组(需要将其序列化为字符串才能存储); json数据——将其转化为字符串存储; 图片 脚本、样式文件:通过ajax
只要能被转化为字符串的数据,都能被localstorage存储;

本地存储如何存储图片

先来看一段代码:
var src="demo.jpg";

function set(key){
var img=document.createElement('img');

img.addEventListener("load",function(){
//创建一个canvas
var imgCanvas=document.createElement("canvas"),
imgContext=imgCanvas.getContext("2d");
//确保canvas元素的大小和图片的尺寸一致
imgCanvas.width=this.width;
imgCanvas.height=this.height;
//渲染图片到canvas中,使用canvas的drawImage()方法
imgContext.drawImage(this,0,0,this.width,this.height);
//用canvas的dataUrl的形式取出图片,imgAsDataURL是一个base64的字符串
var imgAsDataURL=imgCanvas.toDataURL("image/png");
//保存到本地存储中
//使用try-catch()查看是否支持localstorage
try{
localStorage.setItem(key,imgAsDataURL);//将取出的图片存放到localStorage 
}
catch(e) {
console.log("Storage failed:"+e);//存储失败
}

},false);
img.src=src;
} 
function get(key) {//从本地缓存获取图片并且渲染
var srcStr=localStorage.getItem(key);//从localStorage中取出图片
var imgObj=document.createElement('img');//创建一个img标签
imgObj.src=srcStr;
document.body.appendChild(imgObj);
}

注释:
(1)、这个比较适合用在不常更改的图片,但是如果图片的base64大小比较大的话,将比较耗费localStorage的资源;

(2)、canvas有一个安全策略的问题:如果图片和你本身请求的域名不在同一个域名下,浏览器会报出一个安全问题,这个时候我们要给我们的服务器加一个“允许跨域”访问的响应头————Access Orign=*,这样来保证你的图片可进行跨域被canvas来画;

HTML5本地存储需要注意的:

使用前判断浏览器是否支持localStorage;(IOS浏览器在无痕模式浏览下,是无法打开localStorage;以及,其他奇葩浏览器,在存储localstorage的时候报错)
做法:根据前面代码,我们在检查是否支持,先进行setItem()一次,然后对setItem进行异常捕获;
写数据的时候,需要异常处理,避免超出容量抛出错误; 
localStorage本身只有5M;
避免把敏感的信息存入localStorage;
key的唯一性;重复写,将会覆盖之前的key;

HTML5本地存储使用限制:

存储更新策略,过期控制:localStorage是永不过期的,业务上如果想实现一些过期策略,需要在localStorage上加一层处理过期的机制; 各个子域名之间不能共享存储数据;(借助H5的postMessage()这个API做一些跨域上得处理) 超出存储大小之后如何存储——使用一些如LRU、FIFO的算法去淘汰一些旧的数据; server端如何取到数据——使用post/get参数

处理过期控制

先来看一下代码:
function set(key,y){
var curTime=new Date().getTime();
//存储一个当时存储时候的时间
localStorage.setItem(key,JSON.stringify({data:v,time:curTime}));

}
function get(key,exp) {
var data=localStorage.getItem(key);
var dataObj=JSON.parse(data);
if(new Date().getTime()-dataObj.time>exp) {//get出来的时间减去当时存储的时间大于过期时间,那么就认为过期
console.log("过期");
}else {
//否则,返回值
console.log("data="+dataObj.data);
}
}

本地存储使用场景

本地数据存储,减少网络传输 在弱网络的环境下,会发生高延迟,低带宽,应该尽量把数据(如脚本、样式)本地化;
我们来看一张图,显示的是本地存储和网络拉取耗时的对比:
alt text

IndexedDB

概念

IndexedDB,是一种能做浏览器中持久地存储结构化数据的数据库,并且为web应用提供了丰富的查询能力;

支持情况

chrome11+\opera不支持\firefox 4+\IE 10+,移动端浏览器支持能力弱

存储结构

IndexedDB是按域名分配独立空间,一个独立域名下可以创建多个数据库,每个数据库可以创建对个对象存储空间(表/table),一个对象存储空间可以存储多个对象数据;
如图:
alt text

使用IndexedDB实现离线数据库

这里我们主要从IndexedDB 的四大功能入手:
增删改 事务处理 游标 索引
下面我们通过一段代码来讲解,请关注里面的注释:




 
 
 
 
 
 
<script type="text/javascript"> var db; var arrayKey=[]; var openRequest; var lastCursor; var indexedDB=window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;//indexedDB在不同的浏览器下不同 var dbName="person";//数据库名称 var tableName="testTable";//表名称 function init() { openRequest=indexedDB.open(dbName);//页面加载时先打开一个DB,如果该DB存在,则打开;不存在,则新建 //触发事件——当一个“新的数据库”被创建或者数据库的“版本号”被更改时触发 openRequest.onupgradeneeded=function(e){ console.log("onupgradeneeded"); var thisDb=e.target.result; console.log(thisDb.version); //检查这个数据库中是否包含我们要查找的表 if(!thisDb.objectStoreNames.contains(tableName)){ //不包含——创建一个表 console.log("需要创建一个objectStore"); //keyPath:主键,autoIncrement:主键自增 var objectStore=thisDb.createObjectStore(tableName,{keyPath:"id",autoIncrement:true}); //创建表的时候,指定哪些字段是能被索引的 objectStore.createIndex("name","name",{unique:false});//创建索引 objectStore.createIndex("phone","phone",{unique:false}); } } //触发事件——成功打开一个数据库时触发 openRequest.onsuccess=function(e){ db=e.target.result; console.log(db.version); db.onerror=function(event){ alert("数据库错误:"+event.target.errorCode); console.dir(event.target); }; //判断该数据库中有没有这个表 if(db.objectStoreNames.contains(tableName)){ //存在这个表 console.log("包含表:"+tableName); //通过事物机制操作一个表的读写,从而保证数据的一致性和可靠性 var transaction=db.transaction([tableName],"readwrite"); //事物的事件 transaction.oncomplete=function(event){ console.log("完成"); }; transaction.onerror=function(event){ console.dir(event); }; var objectStore=transaction.objectStore(tableName);//通过事物获取表中一个objectStore对象,即表的对象 //遍历表的记录——游标-openCursor,这是indexedDb的重点 objectStore.openCursor().onsuccess=function(event){ var cursor=event.target.result; if(cursor){ console.log(cursor.key); console.dir(cursor.value); render({key:cursor.key,name:cursor.value["name"],phone:cursor.value["phone"],address:cursor.value["address"]}); lastCursor=cursor.key;//如果不设置lastCursor,那么游标默认是下一条接着下一条来遍历;设置了lastCursor,游标将循环遍历 cursor.continue(); }else { console.log("请使用游标来搞定"); } }; objectStore.openCursor().onerror=function(event){ console.dir(event); }; } } //添加新记录 document.querySelector("#add").addEventListener("click",function(){ var name=document.querySelector("#name").value(); var phone=document.querySelector("#phone").value(); var address=document.querySelector("address").value(); var person={"name":name,"phone":phone,"address":address};//设置对象 //通过事务——操作表 var transaction=db.transaction([tableName],"readwrite"); transaction.oncomplete=function(event){ console.log("事务处理完成"); }; transaction.onerror=function(event){ console.dir(event); }; var objectStore=transaction.objectStore(tableName);//创建一个表对象 objectStore.add(person);//添加对象到表中——add() //将新增的记录显示处理 objectStore.openCursor().onsuccess=function(event){ cursor=event.target.result; var key; if(lastCursor==null){ key=cursor.key; lastCursor=key; }else { key=++lastCursor; } render({key:key,name:name,phone:phone,address:address}); console.log("成功添加新记录:"+key); console.dir(person); } }); //删除指定ID function deleteRecord(id){ var transaction=db.transaction([tableName],"readwrite"); transaction.oncomplete=function(event){ console.log("事务处理完成"); }; transaction.onerror=function(event){ console.dir(event); }; var objectStore=transaction.objectStore(tableName); var removeKey=parseInt(id); var getRequest=objectStore.get(removeKey);//获取索引值---get() getRequest.onsuccess=function(e){ var result=getRequest.result; console.dir(result); } var request=objectStore.delete(removeKey);//删除——delete request.onsuccess=function(e){ console.log("删除成功"); }; request.onerror=function(e){ console.log("删除错误"+e); }; //隐藏删除的DOM document.getElementById(removeKey).style.display="none"; } //查询记录 document.querySelector("#seletBtn").addEventListener("click",function(){ var curName=document.getElementById("selname").value; var transaction=db.transaction([tableName],"readwrite"); transaction.oncomplete=function(event){ console.log("事务处理完成"); }; transaction.onerror=function(event){ console.dir(event); }; var objectStore=transaction.objectStore(tableName); var boundKeyRange=IDBKeyRange.only(curName);//生成一个表示范围的Range对象---IDBKeyRange,有4个方法,only\lowerBound\upperBound\bound objectStore.index("name").openCursor(boundKeyRange).onsuccess=function(event){ //从indexedDb中找到name var cursor=event.target.result; if(!cursor){ return; } var rowData=cursor.value; console.log(rowData); document.getElementById('content').innerHTML=""; render({key:cursor.value.id,name:cursor.value["name"],phone:cursor.value["phone"],address:cursor.value["address"]}); cursor.continue(); }; }); //删除数据库 document.querySelector("#deleteDB").addEventListener("click",function(){ //使用deleteDatabase() var deleteDB=indexedDB.deleteDatabase(dbName); var content=document.querySelector("#content"); while(content.firstChild){ content.removeChild(content.firstChild); } deleteDB.onsuccess=function(event){ console.log("删除成功"); }; deleteDB.onerror=function(event){ console.dir(event.target); }; }); //渲染 function render(opt){ var child_node = document.createElement("div"); var child_node_child1 = document.createElement("div"); var child_node_child2 = document.createElement("div"); var child_node_child3 = document.createElement("div"); var child_node_child4 = document.createElement("div"); child_node_child1.setAttribute("class","table_child"); child_node_child2.setAttribute("class","table_child"); child_node_child3.setAttribute("class","table_child"); child_node_child4.setAttribute("class","table_child"); child_node_child1.setAttribute("style","float:left"); child_node_child2.setAttribute("style","float:left"); child_node_child3.setAttribute("style","float:left"); child_node_child4.setAttribute("style","float:left"); child_node_child1.innerHTML = name; child_node_child2.innerHTML = opt.phone; child_node_child3.innerHTML = opt.address; child_node_child4.innerHTML = "" child_node.appendChild(child_node_child1); child_node.appendChild(child_node_child2); child_node.appendChild(child_node_child3); child_node.appendChild(child_node_child4); child_node.setAttribute("class","table_tr"); child_node.setAttribute("id",opt.key); var content = document.getElementById('content'); content.appendChild(child_node) } } </script>

离线缓存——application Cache

何为离线缓存

它是能让web应用在离线的情况下继续使用,通过一个叫manifest的文件指明需要缓存的资源;你可以通过navigator.online检测是否在线;

原理

如图:
alt text
解释:
(1)用户通过浏览器(browser)去访问应用,首先检测浏览器是否有一个叫做“App cache”的东西存在,如果存在,则从中检索出app cache所要缓存的list,然后把资源(缓存在浏览器中)拉取出来,返回给用户;
(2)在访问的同时,会检查server上一个叫做manifest的文件,如果该文件有更新,就把manifest指定的文件从server端重新拉取一次,然后把这些缓存在浏览器中,并更新相应的app cache文件;如果manifest这个文件没有更新,那么就啥也不做。
从上图,我们总结2点:
缓存机制的改变,会更新app cache.但是,用户访问,会返回上一次的结果。这样一来,会有一个麻烦,即如果你的业务发生更改,你就需要去更新一次manifest。
注意:更改完,第一次是不生效的,只有第二次刷新才会生效;
如果有一个文件要更新,你就要去更新manifest,而更新manifest文件,它会把server上的文件全部重新拉取一次,而非只是拉取你需要更改的那个文件,这就会造成损耗;

浏览器支持情况

safari on ios 3.2+\android 1,5+\window phone 9+

应用

例子:cache.appcache
CACHE MANIFEST

#version 1.0

CACHE:

#需要缓存的文件
/css/a.css
/js/a/js
/images/a.png

NETWORK:

#每次重新拉取的文件

*

FALLBACK

#离线状况下代替的文件

/404.html
在页面上引入manifest文件:
在服务器添加mime-type text/cache-manifest
如果在服务器上添加:
找到你的xampp/apache/conf目录,找到mime.types文件,在最后面添加一条记录:
text/cache-manifest appcache (appcache是后缀名,你可以选择其他的)
我们来看一个例子:





<script type="text/javascript"> window.addEventListener('load',function(e){ //监听app cache的updateready事件 window.applicationCache.addEventListener('updateready',function(e)){ console.log(window.applicationCache.status); if(window.applicatioinCache.status==window.applicationCache.UPDATEREADY){ //application cache的版本号发生改年 window.applicationCache.swapCache(); window.location.reload(); }else { console.log("manifest没有更改"); } },false); },false); </script>

注意:
app cache会自动地将本页当做一个静态页缓存;
如果你要更新,请更新server端的manifest文件的版本;
如果你不想启用app cache,或者说现在app cache不适合你现在的应用,那么有一个做法:
更改server端上manifest文件的名称,例如cache1.appcache,这个时候再去刷新浏览器,首先,浏览器还是会从app cache缓存中读取缓存,到第二次刷新的时候,浏览器会到server端查找manifest文件,发现这个文件不存在,那么浏览器会走网络从Server上重新拉取文件;

app cache优势:

完全离线 资源缓存,加载更快 降低服务器负载

app cache缺陷:

含有manifest属性的当前请求页无论如何都会被缓存; 更新需要建立在manifest文件的更新,文件更新后是需要页面再次刷新的,并且在第2次刷新才能获取新资源; 更新是全局性的,无法单独更新某个文件; 对于链接的参数变化的敏感的,任何一个参数的修改都会被重新缓存,例如:index.html和index.html?v=1会被认为是不同文件,分别缓存;

app cache适用场景

单地址页面 对实时性要求不要的业务 离线web应用

总结

在实际应用中,我们需要根据业务的需要来采取相应的缓存措施,如上所述,html5的几种缓存都有各自的优缺点和适用场景,有时我们也需要组合使用。
关于HTML5缓存我们就介绍到这里。

参考

Vue Todo local storage

    {{testTodo}}
  • {{todo.title}}

Vue localstorage plugin

counter: {{setCounter}}

Blogger API Vuejs

Total Posts:{{bloggerData.posts.totalItems}}
new Vue({
  el: '#app',
  data(){
    return{
      bloggerData: null
    }
  },
  mounted(){
    var vm = this
    vm.fetchBloggerApi()
  },
  methods:{
    fetchBloggerApi(){
      var vm = this; 
      axios.get('https://www.googleapis.com/blogger/v3/blogs/2050012838741546861?key=YOUR_API_KEYS')
      .then(function (response) {
        vm.bloggerData = response.data
      })
      .catch(function (error) {
        console.log(error);
      });
    }
  }
})

Multiple remove from object

Add User

Options

  • {{ option.name }}


Add User

Options

  • {{ option.name }}

Vue.component("checkbox", {
  template: "#checkbox-template",
  props: [ "id", "value", "val"],
  
  data() {
    return {
      proxy: false
    };
  },
  
  computed: {
    checked: {
      get() {
        return this.value;
      },
      set(value) {
        this.proxy = value;
      }
    }
  },
  
  methods: {
    onChange(event) {
      console.log(this.val )
      this.$emit("input", this.proxy);
    }
  }
});
new Vue({
  el: "#app",
  data() {
    return {
      options: [{
        id: 0,
        name: "John",
        age: 32,
        completed:false
      }, {
        id:1,
        name: "Lance",
        age: 28,
        completed:false
      }],
      addUser:{
        name: '',
        age: 0,
        completed: false
      },
      selected: [],
      filters: {
        notDone: function(option) {
          return !option.completed;
        }
      }
    }
  },
  methods:{
    destroyUser(){
      this.options = this.options.filter(this.filters.notDone);
    },
    setUser(){
      this.options.push(_.clone(this.addUser))
    }
  }
});

How to reshape an array with lodash

.zip.apply(, _.chunk("Your array", "columns"));
How this works:
Let's say you have an array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, etc]
_.chunk(array, 3) will give you [ [1,2,3], [4,5,6], [7,8,9], [10,11,12], [13, 14] ]
.zip.apply(, _.chunk(array, 3)); will give you: [ [1,4,7,10,13], [2,5,8,11,14], [3,6,9,12] ]




var data =  [ [ "a", "b" ], [ "c", "d" ] ];
new Vue({
  el: '#app',
  template: '#main',
  data() {
    return {
      renderItem:
        i => new Vue({
          template: `
            
#{{ dataReturn }}
`, data() { return { index: i }; }, computed:{ dataReturn(){ return data[this.index] } } }) }; } });

Dinner Decider vuejs lodash

{{randomDinnerChoose | capitalize}}

{{dinnerChooser}}

{{randomDinnerChoose | capitalize}}

{{dinnerChooser}}

new Vue({
  el:'#app',
  data(){
    return{
      dinnerChooser: ['dairy','seafood','pasta','vegetable','egg','fish a'],
      incrementDinner: 0,
      inputDinner: '',
      randomDinnerChoose: null
    }
  },
  filters:{
    capitalize(string){
      return _.startCase(string);
    }
    
  },
  methods:{
    addDinner(){
      var vm = this
      if(vm.inputDinner){
        vm.dinnerChooser.push(vm.inputDinner) 
      }else{
        alert('put Something')
      }
    },
    randomDinner(){
      var vm = this
      if(vm.incrementDinner == vm.dinnerChooser.length - 1){
        vm.incrementDinner = 0 
        // it will shuffle until the condition was meet
        vm.dinnerChooser = _.shuffle(vm.dinnerChooser);
      }else{
        //else continue the process of increment dinner
        vm.randomDinnerChoose = vm.dinnerChooser[vm.incrementDinner]
        vm.incrementDinner++
      }
    }
  }
})

search onsen ui





color

http://jsfiddle.net/xLF38/818/ -- background http://lokeshdhakar.com/projects/color-thief/ == detect https://codepen.io/derz/full/xVzwKX -- codepen https://codepen.io/jakob-e/pen/QMZyJG?q=color+thief&limit=all&type=type-pens

onsen ui

Search input



search



  
    

    
    
    

    
    
    
    

  
  

    
      
      
      
      
      
      
    

    
      
        
          
Friends
{{char}} Ann Taylor
.tab {
  line-height: 1;
}

.tab-icon {
  font-size: 22px;
  padding: 0;
  margin: 0;
}

.tab-label {
  margin: 0;
  padding: 0;
  font-size: 12px;
}

.person-list {
  border-top: none;
}

.person {
  line-height: 1;
}

.person-list-header {
  opacity: 0.6;
}

.person-name {
  line-height: 44px;
}

.person-image {
  width: 30px;
  height: 30px;
  margin-top: 8px;
  border-radius: 2px;
}

list with picture



  
    
    
    
    

    
  

  
    
      
        
Picture List
Eiffel Tower
Paris, France
Eiffel Tower is the symbol of Paris and named by Gustave Eiffel.
Monument Valley
Utah, USA
Director John Ford used Monument Valley for a number of his best-known films.
Mount Fuji
Japan
Mount Fuji is the highest mountain in Japan and a frequent attractive subject of Japanese art.
Tokyo Tower
Tokyo, Japan
Tokyo Tower is a communications and observation tower located in Tokyo, Japan.
.list-item-container {
  line-height: 1;
  padding: 15px 0px 15px 15px;
}

.thumbnail {
  width: 80px;
  height: 80px;
  border-radius: 4px;
  -webkit-border-radius: 4px;
}

.name {
  font-weight: 500;
  line-height: 16px;
  font-size: 15px;
  margin-bottom: 6px;
}

.location {
  font-size: 14px;
  opacity: 0.4;
  margin-bottom: 6px;
}

.desc {
  line-height: 1.2;
  font-size: 13px;
}

self.addEventListener('install', function(event) {
  console.log('[Service Worker] Installing Service Worker ...', event);
});

self.addEventListener('activate', function(event) {
  console.log('[Service Worker] Activating Service Worker ...', event);
  return self.clients.claim();
});

self.addEventListener('fetch', function(event) {
  console.log('[Service Worker] Fetching something ....', event);
  event.respondWith(fetch(event.request));
});

onsen

1. App.vue を書き換える import HomePage from './components/HomePage' import AboutPage from './components/AboutPage' import MenuPage from './components/MenuPage' export default { data () { return { currentPage: 'HomePage' } }, components: { HomePage, AboutPage, MenuPage } } 2 MenuPage.vue を書き換える
{{ item.label }}
import HomePage from './components/HomePage' import AboutPage from './components/AboutPage' import MenuPage from './components/MenuPage' export default { data () { return { essentialLinks: [ { label: 'HomePage', link: 'HomePage', icon: 'fa-book' }, { label: 'AboutPage', link: 'AboutPage', icon: 'fa-book' } ] } }, methods: { onClick (link) { this.$parent.$parent.$parent.$parent.$data.currentPage = link } } }

flexbox card view layout

Flexbox Demo: Card Layouts

geotagg

html,
body,
#map {
  height: 100%;
  width: 100%;
  padding: 0px;
  margin: 0px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  color: #333;
}

.infopop h4 {
  font: 14px/16px Arial, Helvetica, sans-serif;
  font-weight: bold;
  margin: 0 0 0px;
  color: #777;
}

// set center coordinates
var coords = [34.069, -118.293];
// set default zoom level
var zoomLevel = 12;
// initialize map
var map = L.map('map').setView(coords, zoomLevel);
// set source for map tiles
ATTR = '© OpenStreetMap contributors, ' +
  'CC-BY-SA | ' +
  '© CartoDB';
CDB_URL = 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png';
// add tiles to map
L.tileLayer(CDB_URL, {
  attribution: ATTR
}).addTo(map);

var photos = [{
  "lat": 34.04555452,
  "lng": -118.3001509,
  "name": "C.H. Johnston, 1951",
  "url": "http://41.media.tumblr.com/8dd3cc5931650a6a772db77f6fad797b/tumblr_n5c7uw79Yn1tq6tdto1_400.jpg",
  "thumbnail": "http://40.media.tumblr.com/8dd3cc5931650a6a772db77f6fad797b/tumblr_n5c7uw79Yn1tq6tdto1_75sq.jpg"
}, {
  "lat": 34.0522683,
  "lng": -118.2698607,
  "name": "L.A. Paving Co., Inc., 1925",
  "url": "http://41.media.tumblr.com/83454d0e9cddfa5e9dcf2911ad9f803c/tumblr_n3q2xjrmvk1tq6tdto1_400.jpg",
  "thumbnail": "http://41.media.tumblr.com/83454d0e9cddfa5e9dcf2911ad9f803c/tumblr_n3q2xjrmvk1tq6tdto1_75sq.jpg"
}, {
  "lat": 34.06281904,
  "lng": -118.2809651,
  "name": "Buxton & Rosa, 1930",
  "url": "http://36.media.tumblr.com/e46918901ad4cc6547ea27233873e879/tumblr_n3q2pdzLXM1tq6tdto1_400.jpg",
  "thumbnail": "http://40.media.tumblr.com/e46918901ad4cc6547ea27233873e879/tumblr_n3q2pdzLXM1tq6tdto1_75sq.jpg"
}, {
  "lat": 34.06370117,
  "lng": -118.2967767,
  "name": "A. M. Concrete Inc., 1990",
  "url": "http://41.media.tumblr.com/634b3ebae1233626c427dbfc44b3261a/tumblr_n1m6xg3ik81tq6tdto1_400.jpg",
  "thumbnail": "http://41.media.tumblr.com/634b3ebae1233626c427dbfc44b3261a/tumblr_n1m6xg3ik81tq6tdto1_75sq.jpg"
}, {
  "lat": 34.05123715,
  "lng": -118.3195567,
  "name": "Atkinson–Spicer Co., 1926",
  "url": "http://40.media.tumblr.com/1db33e935ff486d74cbe35706fc9855a/tumblr_n2m0o6gcvY1tq6tdto1_400.jpg",
  "thumbnail": "http://36.media.tumblr.com/1db33e935ff486d74cbe35706fc9855a/tumblr_n2m0o6gcvY1tq6tdto1_75sq.jpg"
}, {
  "lat": 34.0696981,
  "lng": -118.3614635,
  "name": "Lew. Odell, 1937",
  "url": "http://36.media.tumblr.com/6737d1a172353dcd80bebe5b56d96150/tumblr_n2m20mOESy1tq6tdto1_400.jpg",
  "thumbnail": "http://41.media.tumblr.com/6737d1a172353dcd80bebe5b56d96150/tumblr_n2m20mOESy1tq6tdto1_75sq.jpg"
}, {
  "lat": 34.0707379,
  "lng": -118.3615279,
  "name": "Frank J. Heilmann, 1937",
  "url": "http://36.media.tumblr.com/1b5550f571e508a7a9ddc057ad07096c/tumblr_n2m24ceaF91tq6tdto1_400.jpg",
  "thumbnail": "http://40.media.tumblr.com/1b5550f571e508a7a9ddc057ad07096c/tumblr_n2m24ceaF91tq6tdto1_75sq.jpg"
}, {
  "lat": 34.06903154,
  "lng": -118.361485,
  "name": "Tryon & Brain, 1925",
  "url": "http://41.media.tumblr.com/58a45a711a9b39015fdb0601585e1b44/tumblr_n2m1viKp6v1tq6tdto1_400.jpg",
  "thumbnail": "http://41.media.tumblr.com/58a45a711a9b39015fdb0601585e1b44/tumblr_n2m1viKp6v1tq6tdto1_75sq.jpg"
}, {
  "lat": 34.07611449,
  "lng": -118.2561439,
  "name": "So. Calif. Gas Co., 1987",
  "url": "http://40.media.tumblr.com/8f7f0543d4f53f114fa866b57465380a/tumblr_n294lvcY9H1tq6tdto1_400.jpg",
  "thumbnail": "http://41.media.tumblr.com/8f7f0543d4f53f114fa866b57465380a/tumblr_n294lvcY9H1tq6tdto1_75sq.jpg"
}, {
  "lat": 34.09311068,
  "lng": -118.2675621,
  "name": "James Martin, 1925",
  "url": "http://40.media.tumblr.com/b4ff9e91abd2ba2d8242da9536aa412c/tumblr_n5c729VoJi1tq6tdto1_400.jpg",
  "thumbnail": "http://40.media.tumblr.com/b4ff9e91abd2ba2d8242da9536aa412c/tumblr_n5c729VoJi1tq6tdto1_75sq.jpg"
}, {
  "lat": 34.10834904,
  "lng": -118.3322972,
  "name": "Geo. A. Shepard, 1926",
  "url": "http://40.media.tumblr.com/tumblr_lu4gtf1ez31qex1i7o1_400.jpg",
  "thumbnail": "http://41.media.tumblr.com/tumblr_lu4gtf1ez31qex1i7o1_75sq.jpg"
}];

var photoLayer = L.photo.cluster().on('click', function(evt) {
  var photo = evt.layer.photo;
  var template = '

{name}

'; evt.layer.bindPopup(L.Util.template(template, photo), { minWidth: 400 }).openPopup(); }); photoLayer.add(photos).addTo(map);

Leaflet geotag

how to save user or any model through using relationship

User::where('id', $user->id)->first()->nanowrimosEmailStatsStatus()->save(new NanowrimosEmailStatsStatus(['StatsSent' => 1]));

Mixed Menus (drop-down + social) vuejs


/* Styles for mixed menu (drop-down + social) */
.nav-mixed {
    display: flex;
    background: hsl(0, 0%, 15%);
    flex-wrap: wrap;
    justify-content: space-between;
}
@media screen and (max-width: 30em){
 .multi-level-nav ul ul li a {
  padding-left: 2em;
 }

 .dropdown-toggle {
  display: none;
 }
}

@media screen and (min-width: 30em){
 .multi-level-nav ul {
        display: flex;
        flex-wrap: wrap;
       
 } 

 .multi-level-nav li {
        flex: 1 0 auto;
  position: relative;
 }

 li.has-children > a {
  padding-right: 0;
 }

 .multi-level-nav ul ul {
  display: none;
  position: absolute;
  z-index:100;
 }

 .multi-level-nav ul ul li {
        flex: 1 1 auto;
 }

 .multi-level-nav ul .toggled-on {
  display: flex;
 }

 .dropdown-toggle {
  margin: 0;
  padding: 0 .5em;
  border: 0;
  font-family: 'FontAwesome';
  content: "";
  text-transform: lowercase; /* Stop screen readers to read the text as capital letters */
  background-color: transparent;
 }

 .dropdown-toggle:after {
  position: relative;
  top: 0;
  left: 0;
  width: 42px;
  color: white;
  content: "\f107";
  line-height: 1em; 
 }

 .dropdown-toggle:hover,
 .dropdown-toggle:focus {
  background: hsl(0, 0%, 25%);
 }

 .dropdown-toggle.toggle-on:after {
  content: "\f106";
 }
}
.social-menu li a:before {
  font-family: 'Fontawesome';
  -webkit-font-smoothing: antialiased;
  content: '\f08e';
}
 
.social-menu li a[href*="dribbble.com"]::before { content: '\f17d'; }
 
.social-menu li a[href*="facebook.com"]::before { content: '\f09a'; }
 
.social-menu li a[href*="flickr.com"]::before { content: '\f16e'; }
 
.social-menu li a[href*="foursquare.com"]::before { content: '\f180'; }
 
.social-menu li a[href*="github.com"]::before { content: '\f09b'; }
 
.social-menu li a[href*="plus.google.com"]::before { content: '\f0d5'; }
 
.social-menu li a[href*="instagram.com"]::before { content: '\f16d'; }
 
.social-menu li a[href*="jsfiddle.com"]::before { content: '\f1cc'; }
 
.social-menu li a[href*="linkedin.com"]::before { content: '\f0e1'; }
 
.social-menu li a[href*="pinterest.com"]::before { content: '\f0d2'; }
 
.social-menu li a[href*="reddit.com"]::before { content: '\f1a1'; }
 
.social-menu li a[href*="soundcloud.com"]::before { content: '\f1be'; }
 
.social-menu li a[href*="stackoverflow.com"]::before { content: '\f16c'; }
 
.social-menu li a[href*="tumblr.com"]::before { content: '\f173'; }
 
.social-menu li a[href*="twitter.com"]::before { content: '\f099'; }
 
.social-menu li a[href*="vimeo.com"]::before { content: '\f194'; }
 
.social-menu li a[href*="vine.co"]::before { content: '\f1ca'; }
 
.social-menu li a[href*="yelp.com"]::before { content: '\f1e9'; }
 
.social-menu li a[href*="youtube.com"]::before { content: '\f167'; }
 
.social-menu li a[href*="wordpress.com"]::before { content: '\f19a'; }
 
/* Flexbox stuff */
 
.social-menu ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
}
 
/* Base styles that apply to all menus */
.menu-section {
  padding-bottom: 2em;
  margin-bottom: 2em;
  border-bottom: 1px solid hsl(0, 0%, );
}
 
.menu ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  background: hsl(0, 0%, 15%);
}
 
.menu li a {
  display: block;
  text-decoration: none;
  color: white;
  padding: .6em 1em;
}
 
.menu li a:hover {
  background: hsl(0, 0%, 25%);
}

new Vue({
  el:'#app',
  data: {
    toggleOnOff: false,
    selected: 'food'
  },
  computed:{
    onToggle(){
      return {'on-toggle':this.toggleOnOff}
    },
    subMenu(){
      return this.toggleOnOff === true  ? 'toggled-on' : false
    },
    ariaExpanded(){
      return !this.toggleOnOff ? 'true' : 'false'
    }
  },
  methods:{
    toggleOn(selected){
      this.selected = selected 
      this.toggleOnOff = !this.toggleOnOff
    }
  }
})

social menu



.social-menu li a:before {
  font-family: 'Fontawesome';
  -webkit-font-smoothing: antialiased;
  content: '\f08e';
}

.social-menu li a[href*="dribbble.com"]::before { content: '\f17d'; }

.social-menu li a[href*="facebook.com"]::before { content: '\f09a'; }

.social-menu li a[href*="flickr.com"]::before { content: '\f16e'; }

.social-menu li a[href*="foursquare.com"]::before { content: '\f180'; }

.social-menu li a[href*="github.com"]::before { content: '\f09b'; }

.social-menu li a[href*="plus.google.com"]::before { content: '\f0d5'; }

.social-menu li a[href*="instagram.com"]::before { content: '\f16d'; }

.social-menu li a[href*="jsfiddle.com"]::before { content: '\f1cc'; }

.social-menu li a[href*="linkedin.com"]::before { content: '\f0e1'; }

.social-menu li a[href*="pinterest.com"]::before { content: '\f0d2'; }

.social-menu li a[href*="reddit.com"]::before { content: '\f1a1'; }

.social-menu li a[href*="soundcloud.com"]::before { content: '\f1be'; }

.social-menu li a[href*="stackoverflow.com"]::before { content: '\f16c'; }

.social-menu li a[href*="tumblr.com"]::before { content: '\f173'; }

.social-menu li a[href*="twitter.com"]::before { content: '\f099'; }

.social-menu li a[href*="vimeo.com"]::before { content: '\f194'; }

.social-menu li a[href*="vine.co"]::before { content: '\f1ca'; }

.social-menu li a[href*="yelp.com"]::before { content: '\f1e9'; }

.social-menu li a[href*="youtube.com"]::before { content: '\f167'; }

.social-menu li a[href*="wordpress.com"]::before { content: '\f19a'; }

/* Flexbox stuff */

.social-menu ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Base styles that apply to all menus */
.menu-section {
  padding-bottom: 2em;
  margin-bottom: 2em;
  border-bottom: 1px solid hsl(0, 0%, );
}

.menu ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  background: hsl(0, 0%, 15%);
}

.menu li a {
  display: block;
  text-decoration: none;
  color: white;
  padding: .6em 1em;
}

.menu li a:hover {
  background: hsl(0, 0%, 25%);
}
var input = document.getElementById('Files'); var files = input.files; for(var i = 0; i < files.length; i++) { var file = files[0]; var reader = new FileReader; // use HTML5 file reader to get the file   reader.onloadend = function () { // get EXIF data var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));   var lat = exif.GPSLatitude; var lon = exif.GPSLongitude;   //Convert coordinates to WGS84 decimal var latRef = exif.GPSLatitudeRef || "N"; var lonRef = exif.GPSLongitudeRef || "W"; lat = (lat[0] + lat[1]/60 + lat[2]/3600) * (latRef == "N" ? 1 : -1); lon = (lon[0] + lon[1]/60 + lon[2]/3600) * (lonRef == "W" ? -1 : 1);   //Send the coordinates to your map Map.AddMarker(lat,lon); } reader.readAsBinaryString(file); }

https://developers.arcgis.com/javascript/3/sandbox/sandbox.html?sample=fl_featureCollection

Renowned Water Expert Reynold Aquino Offers Exclusive Water Softener Discounts

Los Angeles, California - November 21, 2024 - World-renowned water expert Reynold Aquino is excited to announce exclusive discounts on prem...

Contact Form

Name

Email *

Message *