javascript BlueKai CoreTag - 付费与自然搜索

bk_coretag_paid_vs_natural.js
// FUNCTION : Search Checker
window._bk = window._bk || {};
window._bk.functions = window._bk.functions || {};
window._bk.functions.searchChecker = function() {

	// Check paid
	var paid = false;
	if (document.location.href.indexOf('gclid=') > -1) {
		paid = true;
	}

	// Check search engine
	var search_engine_flag = false;
	var search_type = "none";
	var search_engine = "none";
	if (document.referrer.indexOf('.google.') > -1) {
		search_engine_flag = true;
		search_engine = "google";
	}
	if (document.referrer.indexOf('.bing.') > -1) {
		search_engine_flag = true;
		search_engine = "bing";
	}
	if (document.referrer.indexOf('.yahoo.') > -1) {
		search_engine_flag = true;
		search_engine = "yahoo";
	}

	if (search_engine_flag && paid) {
		search_type = "paid search"
	};
	if (search_engine_flag && !paid) {
		search_type = "natural search"
	};
	return {
		search_type: search_type,
		paid: paid,
		search_engine: search_engine,
		search_engine_flag: search_engine_flag
	}

}

// Paid & Search Checker
bk_addPageCtx("search_type", window._bk.functions.searchChecker().search_type);
bk_addPageCtx("search_engine", window._bk.functions.searchChecker().search_engine);
bk_addPageCtx("paid", window._bk.functions.searchChecker().paid);

javascript 回调,承诺,Asysc等待

script.js
// Use the functions eatBreakfast, eatLunch, eatDinner, and eatDessert to eat your meals in the traditional order.

// Async Await
async function runnAll() {
  try {
    await eatBreakfast();
    await eatLunch();
    await eatDinner();
    await eatDessert();
  } catch (err) {
    console.log(err);
  }
}

runnAll();

// Calling Promise
// eatBreakfast()
//   .then(()=> eatLunch())
//   .then(()=> eatDinner())
//   .then(()=> eatDessert())
//   .catch((err)=> {
//     console.log(err);
//   });

// Promises
function eatBreakfast() {
  return new Promise((resolve, reject) => {
    console.log("The eatBreakfast function started executing.");
    setTimeout(function() {
      addText("You just ate breakfast.");
      resolve();
    }, 800);
  });
}

function eatLunch() {
  return new Promise((resolve, reject) => {
    console.log("The eatLunch function started executing.");
    setTimeout(function() {
      addText("You just ate lunch.");
      resolve();
    }, 300);
  });
}

function eatDinner() {
  return new Promise((resolve, reject) => {
    console.log("The eatDinner function started executing.");
    setTimeout(function() {
      addText("You just ate dinner.");
      resolve();
    }, 600);
  });
}

function eatDessert(callback) {
  return new Promise((resolve, reject) => {
    console.log("The eatDessert function started executing.");
    setTimeout(function() {
      addText("You just ate dessert.");
      resolve();
    }, 40);
  });
}

// Callback - HELL!!!!!
// eatBreakfast( function() {
//   eatLunch( function(){
//     eatDinner(function(){
//       eatDessert();
//     });
//   });
// });

// Do NOT modify below this line until instructed to do so.
// function eatBreakfast(callback) {
//   console.log("The eatBreakfast function started executing.")
//   setTimeout(function() {
//     addText("You just ate breakfast.")
//     if (callback) callback()
//   }, 800)
// }

// function eatLunch(callback) {
//   console.log("The eatLunch function started executing.")
//   setTimeout(function() {
//     addText("You just ate lunch.")
//     if (callback) callback()
//   }, 300)
// }

// function eatDinner(callback) {
//   console.log("The eatDinner function started executing.")
//   setTimeout(function() {
//     addText("You just ate dinner.")
//     if (callback) callback()
//   }, 600)
// }

// function eatDessert(callback) {
//   console.log("The eatDessert function started executing.")
//   setTimeout(function() {
//     addText("You just ate dessert.")
//     if (callback) callback()
//   }, 40)
// }

const textDiv = document.getElementById("text");
function addText(x) {
  textDiv.insertAdjacentHTML("beforeend", `<p>${x}</p>`);
}

javascript 反应组件创建

compCreation
// CLASS
const styles = {
  someClass: {
    color: '#000',
    '&:hover': {
      color: '#404040',
      cursor: 'pointer'
    }
  }
};

class PatientProfile extends Component {
  constructor (props) {
    super(props);
    this.state = {
      value: 0
    };
  }
  
  someFunction = () => {
    this.props...
  }
  
  render() {
    const { value, classes } = this.props;
  
    return (
      <Button onClick={this.someFunction} className={classes.someClass}>
        Some action
      </Button>
    }
}

export default withStyles(styles)(PatientProfile);
// FUNCTION

javascript 节点js + mongoose

app.js
require('dotenv').config()
const createError = require('http-errors')
const express = require('express')
const path = require('path')
const cookieParser = require('cookie-parser')
const logger = require('morgan')
const mongoose = require('mongoose')

const indexRouter = require('./routes/index')

const app = express()

// view engine setup
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')

app.use(logger('dev'))
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, 'public')))

app.use('/', indexRouter)

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404))
})


// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message
  res.locals.error = req.app.get('env') === 'development' ? err : {}

  // render the error page
  res.status(err.status || 500)
  res.render('error')
})

//mongodb connection
mongoose.connect('mongodb://'+process.env.DB_USER+':'+process.env.DB_PWD+'@'+process.env.DB_HOST+'/'+process.env.DB_NAME , {
  useCreateIndex: true,
  useNewUrlParser: true
})
const db = mongoose.connection


module.exports = app
index.js
const express = require('express')
const router = express.Router()
const Article = require('../models/article')
const Category = require('../models/category')

/* GET home page. */
router.get('/', async function(req, res) {
  let articles = await Article.find().populate('category').sort('-date')
  console.log(articles);
  res.render('index', {articles: articles})
})
// manager page
router.get('/manage', async function(req, res) {
  let articles = await Article.find().populate('category').sort('-date')
  console.log(articles);
  res.render('manage', {articles: articles})
})
// writing page
router.get('/writePost', async function(req,res,next){
  let categories = await Category.find()
  res.render('writePost',{categories:categories})
})
// edit page
router.get('/edit_post/:id', async function(req, res) {
  let article = await Article.findById(req.params.id)
  let categories = await Category.find()
  res.render('editPost',{article:article,categories:categories})
})
// edit db
router.post('/updatePost', async function(req,res,next){
  let article = await Article.findById(req.body._id)
  article.title = req.body.title
  article.description = req.body.description
  article.category = req.body.category
  article.save()
  res.redirect('/manage')
})
// database handler
router.post('/new_post', function(req, res) {
  let article = new Article
  article.title = req.body.title
  article.description = req.body.description
  article.date = Date()
  article.category = req.body.category
  article.save()
  res.redirect('/')
})

router.post('/new_category', function(req, res) {
  let category = new Category
  category.name = req.body.name
  category.save(function(err, category) {
    if (err) console.log(err)
    res.send(category)
  })
})

router.post('/delete_post', async function(req,res,next){
  let articleId = req.body.articleId
  let article = await Article.findById(articleId)
  article.remove()
  res.send(article)
})


module.exports = router
article.js
const mongoose = require('mongoose')

const ArticleSchema = new mongoose.Schema({
  title: {
    type: String,
    unique: true
  },
  description: String,
  date: Date,
  thumbnail: String,
  category: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Category'
  }
})

const Article = mongoose.model('Article', ArticleSchema)
module.exports = Article
category.js
const mongoose = require('mongoose')

const CategorySchema = new mongoose.Schema({
  name: String
})

const Category = mongoose.model('Category', CategorySchema)
module.exports = Category
index.pug
extends layout

block content
  a(href='/manage')
    button.btn_manage MANAGE
  a(href='/writePost')
    button.btn_new NEW
  div.title
    h1 ARTICLES
  div.articles  
    each article in articles
      div.article
        h1= article.title
        p= article.description
        h4= article.category.name
        div.btnArea
    
writePost.pug
extends layout

block content
  a(href='/')
    button.btn_manage BACK
  div.articles
    h1 Article writer
    form(method="POST" action="/new_post")
      h4 title
      input(type="text" name="title")
      h4 description
      input(type="text" name="description")
      h4 category
      select(name="category")
        each category in categories
          option(value=category._id)= category.name
      input(type="submit")
      
    
block scripts
manage.pug
extends layout

block content
  a(href='/')
    button.btn_manage BACK
  div.title
    h1 ARTICLES
  div.articles
    each article in articles
      div.article(data-id=article._id)
        h1= article.title
        p= article.category.name
        p= article.description
        div.btnArea
          a(href='/edit_post/'+article._id).smallBtn.editBtn edit
          a(href='#').smallBtn.deleteBtn delete
block scripts
  script(src='js/manage.js')
editPost.pug
extends layout

block content
  a(href='/')
    button.btn_manage BACK
  div.articles
    h1 Article writer
    form(method="POST" action="/updatePost")
      input(type="hidden" name="_id" value=article._id)
      h4 title
      input(type="text" name="title" value=article.title)
      h4 description
      input(type="text" name="description" value=article.description)
      h4 category
      select(name="category")
        each category in categories
          option(value=category._id selected=(category._id.toString()==article.category ? true : false))= category.name
      input(type="submit")
      
block scripts
manage.js
$(function() {
  $('.deleteBtn').on('click', function(e) {
    e.preventDefault()
    //get article id from the closest object that has the class
    let articleId = $(this).closest('.article').attr('data-id')
    $.ajax({
      url: '/delete_post',
      type: 'POST',
      data: {
        articleId: articleId
      },
      success: function(data) {
        if(data != undefined){
            $('.article[data-id='+articleId+']').remove()
            console.log('deleted');
        }else{
          console.log('failed');
        }
      },
      error: function(request, status, error) {
        console.log('code: ' + request.status + ' error: ' + error)
      }
    })
  })
})

javascript 对含有parent_id的数组进行拓扑排序,然后生成树状结构

对含有parent_id的数组进行拓扑排序,然后生成树状结构

arrty_to_tree.js
const _ = require("lodash");
// 按扭ID(整型,不可重复),按扭名称(字符串),父ID(按扭之间的关系,可为空)
// 100,桌面,0
// 101,开启桌面整理,100
// 102,退出桌面整理,100
// 103,一键桌面整理,100
const file = [["按扭ID(整型,不可重复)", "按扭名称(字符串)", "父ID(按扭之间的关系,可为空)"], ["100", "桌面", "0"], ["101", "开启桌面整理", "100"], ["102", "退出桌面整理", "100"], ["103", "一键桌面整理", "100"], ["104", "新建分区", "100"], ["105", "新建分区-桌面右键", "104"], ["106", "新建分区-分区右键", "104"], ["107", "新建分区-标题栏", "104"], ["108", "解散分区", "100"], ["109", "解散分区-分区右键", "108"], ["110", "解散分区-菜单面板", "108"], ["111", "解散分区-标题栏", "108"], ["112", "锁定分区", "100"], ["113", "锁定分区-菜单面板", "112"], ["114", "锁定分区-标题栏", "112"], ["115", "重命名", "100"], ["116", "查看方式", "100"], ["117", "查看方式-分区右键", "116"], ["118", "大图标", "117"], ["119", "中等图标", "117"], ["120", "小图标", "117"], ["121", "查看方式-菜单面板", "116"], ["122", "大图标", "121"], ["123", "中等图标", "121"], ["124", "小图标", "121"], ["125", "查看方式-底部栏", "116"], ["126", "切换至图标模式", "125"], ["127", "切换至列表模式", "125"], ["128", "查看方式-桌面右键", "116"], ["129", "大图标", "128"], ["130", "中等图标", "128"], ["131", "小图标", "128"], ["132", "自动排列", "128"], ["133", "开启自动排列", "132"], ["134", "关闭自动排列", "132"], ["135", "双击隐藏桌面图标", "128"], ["136", "开启双击隐藏", "135"], ["137", "关闭双击隐藏", "135"], ["138", "显示桌面图标和格子", "128"], ["139", "显示桌面图标和格子", "138"], ["140", "不显示桌面图标和格子", "138"], ["141", "快捷方式小箭头", "128"], ["142", "显示小箭头", "141"], ["143", "不显示小箭头", "141"], ["144", "排序方式", "100"], ["145", "排序方式-分区右键", "144"], ["146", "排序-名称", "145"], ["147", "排序-项目类型", "145"], ["148", "排序-大小", "145"], ["149", "排序-修改时间", "145"], ["150", "排序方式-菜单面板", "144"], ["151", "排序-名称", "150"], ["152", "排序-项目类型", "150"], ["153", "排序-大小", "150"], ["154", "排序-修改时间", "150"], ["155", "排序方式-底部栏", "144"], ["156", "排序-名称", "155"], ["157", "排序-项目类型", "155"], ["158", "排序-大小", "155"], ["159", "排序-修改时间", "155"], ["160", "置顶", "100"], ["161", "取消置顶", "100"], ["162", "移入回收站", "100"], [], [], ["200", "主面板", "0"], ["201", "新建标签", "200"], ["202", "新建标签-标签栏空白处右键", "201"], ["203", "新建标签-标签栏底部按钮", "201"], ["204", "新建标签-空白标签", "201"], ["205", "新建标签-桌面分区", "201"], ["206", "删除标签", "200"], ["207", "删除标签-标签处右键", "206"], ["208", "删除标签-标签内空白处右键", "206"], ["209", "删除标签-桌面分区", "206"], ["210", "删除标签-普通", "206"], ["211", "贴边隐藏", "200"], ["212", "贴边隐藏-顶部右侧", "211"], ["213", "贴边隐藏-顶部左侧", "211"], ["214", "贴边隐藏-顶部中间", "211"], ["215", "贴边隐藏-左侧上边", "211"], ["216", "贴边隐藏-左侧中间", "211"], ["217", "贴边隐藏-左侧下边", "211"], ["218", "贴边隐藏-右侧上边", "211"], ["219", "贴边隐藏-右侧中间", "211"], ["220", "贴边隐藏-右侧下边", "211"], ["221", "查看方式", "200"], ["222", "查看方式-标签内空白处右键", "221"], ["223", "大图标", "222"], ["224", "中等图标", "222"], ["225", "小图标", "222"], ["226", "查看方式-标签处右键", "221"], ["227", "大图标", "226"], ["228", "中等图标", "226"], ["229", "小图标", "226"], ["230", "查看方式-底部栏", "221"], ["231", "大图标", "230"], ["232", "中等图标", "230"], ["233", "小图标", "230"], ["234", "排序方式", "200"], ["235", "排序方式-标签内空白处右键", "234"], ["236", "排序-名称", "235"], ["237", "排序-项目类型", "235"], ["238", "排序-大小", "235"], ["239", "排序-修改时间", "235"], ["240", "排序方式-标签处右键", "234"], ["241", "排序-名称", "240"], ["242", "排序-项目类型", "240"], ["243", "排序-大小", "240"], ["244", "排序-修改时间", "240"], ["245", "排序方式-底部栏", "234"], ["246", "排序-名称", "245"], ["247", "排序-项目类型", "245"], ["248", "排序-大小", "245"], ["249", "排序-修改时间", "245"], ["250", "窗口", "200"], ["251", "放大", "250"], ["252", "缩小", "250"], ["253", "文件", "200"], ["254", "打开", "253"], ["255", "删除", "253"], ["256", "打开文件所在位置", "253"], [], [], ["300", "设置", "0"], ["301", "基础设置", "300"], ["302", "开机时整理桌面", "301"], ["303", "开启", "302"], ["304", "关闭", "302"], ["305", "启动时显示主面板", "301"], ["306", "开启", "305"], ["307", "关闭", "305"], ["308", "桌面", "300"], ["309", "分区设置", "308"], ["310", "收起后,鼠标移到标题自动展开", "309"], ["311", "开启", "310"], ["312", "关闭", "310"], ["313", "快捷操作", "308"], ["314", "双击桌面空白处,隐藏桌面图标", "313"], ["315", "开启", "314"], ["316", "关闭", "314"], ["317", "提醒设置", "308"], ["318", "双击桌面空白处隐藏桌面图标时提醒", "317"], ["319", "开启", "318"], ["320", "关闭", "318"], ["321", "主面板", "300"], ["322", "标签设置", "321"], ["323", "标签切换", "322"], ["324", "鼠标悬停切换标签", "323"], ["325", "鼠标单击切换标签", "323"], ["326", "操作设置", "321"], ["327", "打开交互", "326"], ["328", "鼠标单击打开文件或应用", "327"], ["329", "鼠标双击打开文件或应用", "327"], ["330", "窗口显示", "321"], ["331", "停靠在桌面边缘时自动吸附隐藏", "330"], ["332", "开启", "331"], ["333", "关闭", "331"], ["334", "始终保持在其他窗口前端", "330"], ["335", "开启", "334"], ["336", "关闭", "334"], ["337", "关于", "300"], ["338", "点击检查更新", "337"], ["339", "点击官网", "337"], [], [], [], ["400", "托盘", "0"], ["401", "左键单击", "400"], ["402", "右键单击", "400"], ["403", "主面板", "402"], ["404", "设置", "402"], ["405", "退出", "402"], ["406", "退出", "402"]]
const data = file.map(tuple=>({
  self_id:tuple[0],
  button_name:tuple[1],
  parent_id:tuple[2],
}))

function QueueTree(data){
  let root = {self_id: '0', children:[]};
  let nodes = [root];
  
  let queue = _.clone(data);
  while(!_.isEmpty(queue)){
    const top = queue.shift();
    const {self_id, button_name, parent_id} = top;
    
    let node = {
      self_id,
      button_name,
      parent_id,
      children: []
    }
  
    let parent = _.find(nodes, {self_id: parent_id});
    if (parent) {
      parent.children.push(node)
      nodes.push(node)
    } else {
      nodes.push(node)
    }
  }
  console.log(root)
  console.log(JSON.stringify(root))
}

// 拓扑排序: DFS 深度优先搜索完成之后。按照完成时间从大到小的顺序对结点排序。
function TOPOLOGICAL_SORT(data){
  let graph = DFS(data)
  
  // 按照完成时间从大到小的顺序对结点排序。
  const sortedGraph  = _.sortBy(graph, 'f_time')
  console.log("拓扑排序", sortedGraph.map(n => [n.f_time, n.self_id, n.parent_id]))
    
  return sortedGraph;
}

let globalTime = 1;
// 深度优先搜索
function DFS(data){
  let graph = data.map(node =>({
    ...node,
    color: "white",
    // children: []
  }))
  _.forEach(graph, (node)=>{
    DFS_VISIT(graph, node)
  })

  return graph;
  // console.log(graph)
  // console.log(JSON.stringify(graph))
}
// 深度优先搜索
function DFS_VISIT(graph, node){
  globalTime += 1
  node.d_time = globalTime
  node.color = 'gray'
  
  // 找到所有当前节点的孩子
  let children = _.filter(graph, {parent_id: node.self_id})
  _.forEach(children, (child)=>{
    if (child && child.color == 'white'){
      // node.children.push(child)
      DFS_VISIT(graph, child)
    }
  })
  node.color = 'black'
  globalTime += 1
  node.f_time = globalTime
}
// TOPOLOGICAL_SORT(data)
// DFS(data);
let sortedQueue = TOPOLOGICAL_SORT(data);
QueueTree(sortedQueue)



    let parent = _.find(nodes, {self_id: parent_id});
    if (parent) {
      parent.children.push(node)
      nodes.push(node)
    } else {
      nodes.push(node)
    }
  }
  console.log(root)
  console.log(JSON.stringify(root))
}

// 拓扑排序: DFS 深度优先搜索完成之后。按照完成时间从大到小的顺序对结点排序。
function TOPOLOGICAL_SORT(data){
  let graph = DFS(data)
  
  // 按照完成时间从大到小的顺序对结点排序。
  const sortedGraph  = _.sortBy(graph, 'f_time')
  console.log("拓扑排序", sortedGraph.map(n => [n.f_time, n.self_id, n.parent_id]))
    
  return sortedGraph;
}

let globalTime = 1;
// 深度优先搜索
function DFS(data){
  let graph = data.map(node =>({
    ...node,
    color: "white",
    // children: []
  }))
  _.forEach(graph, (node)=>{
    DFS_VISIT(graph, node)
  })

  return graph;
  // console.log(graph)
  // console.log(JSON.stringify(graph))
}
// 深度优先搜索
function DFS_VISIT(graph, node){
  globalTime += 1
  node.d_time = globalTime
  node.color = 'gray'
  
  // 找到所有当前节点的孩子
  let children = _.filter(graph, {parent_id: node.self_id})
  _.forEach(children, (child)=>{
    if (child && child.color == 'white'){
      // node.children.push(child)
      DFS_VISIT(graph, child)
    }
  })
  node.color = 'black'
  globalTime += 1
  node.f_time = globalTime
}
// TOPOLOGICAL_SORT(data)
// DFS(data);
let sortedQueue = TOPOLOGICAL_SORT(data);
QueueTree(sortedQueue)


javascript JavaScript的测试

JavaScript的测试

test-3.js
// test-3.js

const { suma, resta } = require( './funcionesMatematicas' )
const { esperoQue } = require( './funcionesTesting' )

let resultado, esperado

resultado = suma( 2, 3 )
esperado = 5
esperoQue( resultado ).seaIgualQue( esperado )

resultado = resta( 8, 3 )
esperado = 5
esperoQue( resultado ).seaIgualQue( esperado )

console.log( '¡Test3 OK! 

javascript JavaScript的测试

JavaScript的测试

funcionesTesting_1.js
// funcionesTesting.js

const esperoQue = ( dato ) => {
  return {
    seaIgualQue: ( esperado ) => {
      if ( dato !== esperado ) {
        throw new Error( `${ dato } es distinto que ${ esperado }` )
      }
      // También podríamos usar 

javascript 没有JSX示例

noJSX
const Example = () => {
    return (
        // Sans JSX:
        // React.createElement("div", { className: "book"}, 
        //     React.createElement("h2", { className: "title" }, "Title here"),
        //     React.createElement("h3", { className: "author" }, "Author here"),
        //     React.createElement("ul", { className: "stats" }, 
        //         React.createElement("li", { className: "rating" }, "5 stars"),
        //         React.createElement("li", { className: "isbn" }, "12-345678-910")
        //     )
        // )

        // Makes you appreciate JSX, yeah?
        <div className="book">
            <h2 className="title">Title here</h2>
            <h3 className="author">Author here</h3>
            <ul className="stats">
                <li className="rating">5 stars</li>
                <li className="isbn">12-345678-910</li>
            </ul>
        </div>
    )
}

javascript 客户端验证

如果将其绑定到按钮,请确保将其与返回绑定。这可以防止按钮在无效时触发。 <br/> ###注意:将值返回到控件以禁用它,防止在选择新文件时删除文件上载器中的文件。要解决此问题,请不要返回false,而是禁用以编程方式提交按钮##

ClientValidation.js
If you are binding it directly to the submit button
Do NOT bind it with return, as it will not work with file uploaders i.e.
<button type="submit" onclick="return ValidateFileUpload() ">Submit application</button>

// Do it this way.
<button type="submit" onclick="ValidateFileUpload() ">Submit application</button>

function ValidateFileUpload(fileUplaoder) {
    document.getElementById('submit').disabled = false;
    
    if (fileList.innerHTML.trim().length < 1) {
        errorSpan.style.color = "red";
        errorSpan.parentNode.style.borderColor = "red";
        document.getElementById('submit').disabled = true;
    }
    document.getElementById('submit').disabled = false;
}

javascript 露西光滑滚动

Lucy.js

/**
 * Written by Mineo Okuda on 01/03/18.
 *
 * Mineo Okuda - development + design
 * https://willstyle.co.jp
 * https://github.com/min30327
 *
 * MIT license.
 */


		var defaults = {
			wrapper: '#luxy',
			targets : '.luxy-el',
			wrapperSpeed: 0.08,
			targetSpeed: 0.02,
			targetPercentage: 0.1
		};

 		var requestAnimationFrame = 
			window.requestAnimationFrame || window.mozRequestAnimationFrame ||
			window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
			window.requestAnimationFrame = requestAnimationFrame;
		var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;

		/**
		 * Merge two or more objects. Returns a new object.
		 * @param {Object}   objects  The objects to merge together
		 * @returns {Object}          Merged values of defaults and options
		 */
		var extend = function () {

			// Variables
			var extended = {};
			var deep = false;
			var i = 0;
			var length = arguments.length;

			// Merge the object into the extended object
			var merge = function (obj) {
				for (var prop in obj) {
					if (obj.hasOwnProperty(prop)) {
						extended[prop] = obj[prop];
					}
				}
			};

			// Loop through each object and conduct a merge
			for ( ; i < length; i++ ) {
				var obj = arguments[i];
				merge(obj);
			}

			return extended;

		};

		
		function Luxy(){
			this.Targets = [];
			this.TargetsLength = 0;
			this.wrapper = '';
			this.windowHeight = 0;
			this.wapperOffset = 0;
		};
  
		
			Luxy.prototype.isAnimate =  false;
			Luxy.prototype.isResize = false;
			Luxy.prototype.scrollId = "";
			Luxy.prototype.resizeId = "";
  
		
			Luxy.prototype.init = function(options){
				this.settings = extend(defaults, options || {});
				this.wrapper = document.querySelector(this.settings.wrapper);

				if(this.wrapper==="undefined"){
					return false;
				}
				this.targets = document.querySelectorAll(this.settings.targets);
				document.body.style.height = this.wrapper.clientHeight + 'px';

				this.windowHeight = window.clientHeight;
				this.attachEvent();
				this.apply(this.targets,this.wrapper);
				this.animate();
				this.resize();
			};
  
			Luxy.prototype.apply = function(targets,wrapper){
				this.wrapperInit();
				
				this.targetsLength = targets.length;
				for (var i = 0; i < this.targetsLength; i++) {
					var attr = {
						offset : targets[i].getAttribute('data-offset'),
						speedX : targets[i].getAttribute('data-speed-x'),
						speedY : targets[i].getAttribute('data-speed-Y'),
						percentage : targets[i].getAttribute('data-percentage'),
						horizontal : targets[i].getAttribute('data-horizontal')
					};
					this.targetsInit(targets[i],attr);
				}
			};

			Luxy.prototype.wrapperInit = function(){
				this.wrapper.style.width = '100%';
				this.wrapper.style.position = 'fixed';
			};

			Luxy.prototype.targetsInit = function(elm,attr){
				
				this.Targets.push({
					elm : elm,
					offset : attr.offset ? attr.offset : 0,
					horizontal : attr.horizontal ? attr.horizontal : 0,
					top : 0,
					left : 0,
					speedX : attr.speedX ? attr.speedX : 1,
					speedY : attr.speedY ? attr.speedY : 1,
					percentage :attr.percentage ? attr.percentage : 0
				});
			};

			Luxy.prototype.scroll = function(){
				var scrollTopTmp = document.documentElement.scrollTop || document.body.scrollTop;
				this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
				var offsetBottom = this.scrollTop + this.windowHeight;
				this.wrapperUpdate(this.scrollTop);
				for (var i = 0; i < this.Targets.length; i++) {
					this.targetsUpdate(this.Targets[i]);
				}
			};
			Luxy.prototype.animate = function(){
				this.scroll();
				this.scrollId = requestAnimationFrame(this.animate.bind(this));
			};

			Luxy.prototype.wrapperUpdate = function(){
				
				this.wapperOffset += (this.scrollTop - this.wapperOffset) * this.settings.wrapperSpeed;
				this.wrapper.style.transform = 'translate3d(' + 0 + ',' +  Math.round(-this.wapperOffset* 100) / 100 + 'px ,' + 0 + ')';
			};

			Luxy.prototype.targetsUpdate = function(target){
				target.top += (this.scrollTop * Number(this.settings.targetSpeed) * Number(target.speedY) - target.top) * this.settings.targetPercentage;
				target.left += (this.scrollTop * Number(this.settings.targetSpeed) * Number(target.speedX) - target.left) * this.settings.targetPercentage;
				var targetOffsetTop = ( parseInt(target.percentage) - target.top - parseInt(target.offset) );
				var offsetY = Math.round(targetOffsetTop * -100) / 100;
				var offsetX = 0;
				if(target.horizontal){
					var targetOffsetLeft = ( parseInt(target.percentage) - target.left - parseInt(target.offset) );
					offsetX = Math.round(targetOffsetLeft * -100) / 100;
				}
				target.elm.style.transform = 'translate3d(' + offsetX + 'px ,' + offsetY + 'px ,' + 0 +')';
			};

			Luxy.prototype.resize = function(){
				var self = this;
				self.windowHeight = (window.innerHeight || document.documentElement.clientHeight || 0);
				if( parseInt(self.wrapper.clientHeight) != parseInt(document.body.style.height)){
					document.body.style.height = self.wrapper.clientHeight + 'px';
				}
				self.resizeId = requestAnimationFrame(self.resize.bind(self));
			};

			Luxy.prototype.attachEvent = function(){
				var self = this;
				window.addEventListener('resize',function(){
					if(!self.isResize){
						cancelAnimationFrame(self.resizeId);
						cancelAnimationFrame(self.scrollId);
						self.isResize = true;
						setTimeout(function(){
							self.isResize = false;
							self.resizeId = requestAnimationFrame(self.resize.bind(self));
							self.scrollId = requestAnimationFrame(self.animate.bind(self));
						},200);
					}
				});
				
			};
		

		
		var luxy = new Luxy();
Luxy.es6.js

/**
 * Written by Mineo Okuda on 01/03/18.
 *
 * Mineo Okuda - development + design
 * https://willstyle.co.jp
 * https://github.com/min30327
 *
 * MIT license.
 */


const defaults = {
    wrapper: '#luxy',
    targets : '.luxy-el',
    wrapperSpeed: 0.08,
    targetSpeed: 0.02,
    targetPercentage: 0.1
};

const requestAnimationFrame = 
    window.requestAnimationFrame || window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
const cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;

/**
 * Merge two or more objects. Returns a new object.
 * @param {Object}   objects  The objects to merge together
 * @returns {Object}          Merged values of defaults and options
 */
const extend = function(...args) {

    // Variables
    const extended = {};
    const deep = false;
    let i = 0;
    const length = args.length;

    // Merge the object into the extended object
    const merge = obj => {
        for (const prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                extended[prop] = obj[prop];
            }
        }
    };

    // Loop through each object and conduct a merge
    for ( ; i < length; i++ ) {
        const obj = args[i];
        merge(obj);
    }

    return extended;

};


class Luxy {
    constructor() {
        this.Targets = [];
        this.TargetsLength = 0;
        this.wrapper = '';
        this.windowHeight = 0;
        this.wapperOffset = 0;
    }

    init(options) {
        this.settings = extend(defaults, options || {});
        this.wrapper = document.querySelector(this.settings.wrapper);

        if(this.wrapper==="undefined"){
            return false;
        }
        this.targets = document.querySelectorAll(this.settings.targets);
        document.body.style.height = `${this.wrapper.clientHeight}px`;

        this.windowHeight = window.clientHeight;
        this.attachEvent();
        this.apply(this.targets,this.wrapper);
        this.animate();
        this.resize();
    }

    apply(targets, wrapper) {
        this.wrapperInit();
        
        this.targetsLength = targets.length;
        for (let i = 0; i < this.targetsLength; i++) {
            const attr = {
                offset : targets[i].getAttribute('data-offset'),
                speedX : targets[i].getAttribute('data-speed-x'),
                speedY : targets[i].getAttribute('data-speed-Y'),
                percentage : targets[i].getAttribute('data-percentage'),
                horizontal : targets[i].getAttribute('data-horizontal')
            };
            this.targetsInit(targets[i],attr);
        }
    }

    wrapperInit() {
        this.wrapper.style.width = '100%';
        this.wrapper.style.position = 'fixed';
    }

    targetsInit(elm, attr) {
        
        this.Targets.push({
            elm,
            offset : attr.offset ? attr.offset : 0,
            horizontal : attr.horizontal ? attr.horizontal : 0,
            top : 0,
            left : 0,
            speedX : attr.speedX ? attr.speedX : 1,
            speedY : attr.speedY ? attr.speedY : 1,
            percentage :attr.percentage ? attr.percentage : 0
        });
    }

    scroll() {
        const scrollTopTmp = document.documentElement.scrollTop || document.body.scrollTop;
        this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
        const offsetBottom = this.scrollTop + this.windowHeight;
        this.wrapperUpdate(this.scrollTop);
        for (let i = 0; i < this.Targets.length; i++) {
            this.targetsUpdate(this.Targets[i]);
        }
    }

    animate() {
        this.scroll();
        this.scrollId = requestAnimationFrame(this.animate.bind(this));
    }

    wrapperUpdate() {
        
        this.wapperOffset += (this.scrollTop - this.wapperOffset) * this.settings.wrapperSpeed;
        this.wrapper.style.transform = `translate3d(${0},${Math.round(-this.wapperOffset* 100) / 100}px ,${0})`;
    }

    targetsUpdate(target) {
        target.top += (this.scrollTop * Number(this.settings.targetSpeed) * Number(target.speedY) - target.top) * this.settings.targetPercentage;
        target.left += (this.scrollTop * Number(this.settings.targetSpeed) * Number(target.speedX) - target.left) * this.settings.targetPercentage;
        const targetOffsetTop = ( parseInt(target.percentage) - target.top - parseInt(target.offset) );
        const offsetY = Math.round(targetOffsetTop * -100) / 100;
        let offsetX = 0;
        if(target.horizontal){
            const targetOffsetLeft = ( parseInt(target.percentage) - target.left - parseInt(target.offset) );
            offsetX = Math.round(targetOffsetLeft * -100) / 100;
        }
        target.elm.style.transform = `translate3d(${offsetX}px ,${offsetY}px ,${0})`;
    }

    resize() {
        const self = this;
        self.windowHeight = (window.innerHeight || document.documentElement.clientHeight || 0);
        if( parseInt(self.wrapper.clientHeight) != parseInt(document.body.style.height)){
            document.body.style.height = `${self.wrapper.clientHeight}px`;
        }
        self.resizeId = requestAnimationFrame(self.resize.bind(self));
    }

    attachEvent() {
        const self = this;
        window.addEventListener('resize',() => {
            if(!self.isResize){
                cancelAnimationFrame(self.resizeId);
                cancelAnimationFrame(self.scrollId);
                self.isResize = true;
                setTimeout(() => {
                    self.isResize = false;
                    self.resizeId = requestAnimationFrame(self.resize.bind(self));
                    self.scrollId = requestAnimationFrame(self.animate.bind(self));
                },200);
            }
        });
        
    }
}


Luxy.prototype.isAnimate =  false;
Luxy.prototype.isResize = false;
Luxy.prototype.scrollId = "";
Luxy.prototype.resizeId = "";



const luxy = new Luxy();