从零开始实现一个颜色选择器(原生JavaScript实现

for (let k in obj) {

cloneObj[k] = util.isShallowObject(obj[k]) ? f(obj[k]) : obj[k];

}

return cloneObj;

};

util.getCss = (el, prop) => window.getComputedStyle(el, null)[prop];

util.$ = (ident) => {

if (!ident) return null;

return document[

ident.indexOf(“#”) > -1 ? “querySelector” : “querySelectorAll”

](ident);

};

util[“on”] = (element, type, handler, useCapture = false) => {

if (element && type && handler) {

element.addEventListener(type, handler, useCapture);

}

};

util[“off”] = (element, type, handler, useCapture = false) => {

if (element && type && handler) {

element.removeEventListener(type, handler, useCapture);

}

};

util[“getRect”] = (el) => el.getBoundingClientRect();

util[“baseClickOutSide”] = (element, isUnbind = true, callback) => {

const mouseHandler = (event) => {

const rect = util.getRect(element);

const target = event.target;

if (!target) return;

const targetRect = util.getRect(target);

if (

targetRect.x >= rect.x &&

targetRect.y >= rect.y &&

targetRect.width <= rect.width &&

targetRect.height <= rect.height

)

return;

if (util.isFunction(callback)) callback();

if (isUnbind) {

// 延迟解除绑定

setTimeout(() => {

util.off(document, util.eventType[0], mouseHandler);

}, 0);

}

};

util.on(document, util.eventType[0], mouseHandler);

};

util[“clickOutSide”] = (context, config, callback) => {

const mouseHandler = (event) => {

const rect = util.getRect(context.$Dom.picker);

let boxRect = null;

if (config.hasBox) {

boxRect = util.getRect(context.$Dom.box);

}

const target = event.target;

if (!target) return;

const targetRect = util.getRect(target);

// 利用rect来判断用户点击的地方是否在颜色选择器面板区域之内

if (config.hasBox) {

if (

targetRect.x >= rect.x &&

targetRect.y >= rect.y &&

targetRect.width <= rect.width

)

return;

// 如果点击的是盒子元素

if (

targetRect.x >= boxRect.x &&

targetRect.y >= boxRect.y &&

targetRect.width <= boxRect.width &&

targetRect.height <= boxRect.height

)

return;

callback();

} else {

if (

targetRect.x >= rect.x &&

targetRect.y >= rect.y &&

targetRect.width <= rect.width &&

targetRect.height <= rect.height

)

return;

callback();

}

setTimeout(() => {

util.off(document, util.eventType[0], mouseHandler);

}, 0);

};

util.on(document, util.eventType[0], mouseHandler);

};

util[“createUUID”] = () =>

(Math.random() * 10000000).toString(16).substr(0, 4) +

“-” +

new Date().getTime() +

“-” +

Math.random().toString().substr(2, 5);

util.removeAllSpace = (value) => value.replace(/\s+/g, “”);

util.isJQDom = (dom) =>

typeof window.jQuery !== “undefined” && dom instanceof jQuery;

//the event

util.eventType = navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)

? [“touchstart”, “touchmove”, “touchend”]

: [“mousedown”, “mousemove”, “mouseup”];

动画函数的封装


const animation = {};

function TimerManager() {

this.timers = [];

this.args = [];

this.isTimerRun = false;

}

TimerManager.makeTimerManage = function (element) {

const elementTimerManage = element.TimerManage;

if (!elementTimerManage || elementTimerManage.constructor !== TimerManager) {

element.TimerManage = new TimerManager();

}

};

const methods = [

{

method: “add”,

func: function (timer, args) {

this.timers.push(timer);

this.args.push(args);

this.timerRun();

},

},

{

method: “timerRun”,

func: function () {

if (!this.isTimerRun) {

let timer = this.timers.shift(),

args = this.args.shift();

if (timer && args) {

this.isTimerRun = true;

timer(args[0], args[1]);

}

}

},

},

{

method: “next”,

func: function () {

this.isTimerRun = false;

this.timerRun();

},

},

];

methods.forEach((method) =>

util.addMethod(TimerManager, method.method, method.func)

);

function runNext(element) {

const elementTimerManage = element.TimerManage;

if (elementTimerManage && elementTimerManage.constructor === TimerManager) {

elementTimerManage.next();

}

}

function registerMethods(type, element, time) {

let transition = “”;

if (type.indexOf(“slide”) > -1) {

transition = “height” + time + " ms";

util.setCss(element, “overflow”, “hidden”);

upAndDown();

} else {

transition = “opacity” + time + " ms";

inAndOut();

}

util.setCss(element, “transition”, transition);

function upAndDown() {

const isDown = type.toLowerCase().indexOf(“down”) > -1;

if (isDown) util.setCss(element, “display”, “block”);

const getPropValue = function (item, prop) {

let v = util.getCss(item, prop);

return util.removeAllSpace(v).length ? parseInt(v) : Number(v);

};

const elementChildHeight = [].reduce.call(

element.children,

(res, item) => {

res +=

item.offsetHeight +

getPropValue(item, “margin-top”) +

getPropValue(item, “margin-bottom”);

return res;

},

0

);

let totalHeight = Math.max(element.offsetHeight, elementChildHeight + 10);

let currentHeight = isDown ? 0 : totalHeight;

let unit = totalHeight / (time / 10);

if (isDown) util.setCss(element, “height”, “0px”);

let timer = setInterval(() => {

currentHeight = isDown ? currentHeight + unit : currentHeight - unit;

util.setCss(element, “height”, currentHeight + “px”);

if (currentHeight >= totalHeight || currentHeight <= 0) {

clearInterval(timer);

util.setCss(element, “height”, totalHeight + “px”);

runNext(element);

}

if (!isDown && currentHeight <= 0) {

util.setCss(element, “display”, “none”);

util.setCss(element, “height”, “0”);

}

}, 10);

}

function inAndOut() {

const isIn = type.toLowerCase().indexOf(“in”) > -1;

let timer = null;

let unit = (1 * 100) / (time / 10);

let curAlpha = isIn ? 0 : 100;

util.setSomeCss(element, [

{

prop: “display”,

value: isIn ? “none” : “block”,

},

{

prop: “opacity”,

value: isIn ? 0 : 1,

},

]);

let handleFade = function () {

curAlpha = isIn ? curAlpha + unit : curAlpha - unit;

if (element.style.display === “none” && isIn)

util.setCss(element, “display”, “block”);

util.setCss(element, “opacity”, (curAlpha / 100).toFixed(2));

if (curAlpha >= 100 || curAlpha <= 0) {

if (timer) clearTimeout(timer);

runNext(element);

if (curAlpha <= 0) util.setCss(element, “display”, “none”);

util.setCss(element, “opacity”, curAlpha >= 100 ? 1 : 0);

} else {

timer =

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值