zoukankan      html  css  js  c++  java
  • HTML5简易取色器中遇到的jquery闭包问题

    现在在做一个有关图片处理的项目,用到了一些HTML5中的新特性,但是在颜色方面没有找到一个比较好用的取色器,所以就打算自己写一个。

    实现过程比较简单,由于是第一次写类似插件的JS,涉及到了闭包问题,对于我来说还是第一次接触,所以难免遇到一些问题。

    问题描述:

    我 在$.fn.colorpicker = function (callbackFun, colorType)中接收两个参数(回调函数和返回值类型),问题是在我在两个地方调用$.fn.colorpicker并传递不同回调函数参数时,无 法更改包中的callbackFun值,导致每次返回的颜色都传递到第一次调用的回调函数中,希望有大牛帮我解释一下。

    以下是js全部代码(暂时只支持火狐浏览器,其它未作兼容,实现比较匆忙,有什么需要改进的地方欢迎指点)

    /*
    colorpicker 1.0
    Copyright (c) 2013 Jia Wencheng
    Email:jiawencheng06@163.com

    Name:colorpicker

    Description:This a jQuery (Interface) colorpicker.
    */
    (function ($) {
        $.fn.colorpicker = function (callbackFun, colorType) {

            originObj = $(this);
            colorType = colorType;
            callbackFun = callbackFun;

            $(document).ready(function () {
                if (!$("#divMain")[0]) {
                    createElement();
                    initColorMapBar();
                    initColorMap([0, 0, 0]);
                }
            });

            if ($("#divMain").css("display") == "none") {
                $("#divMain").css("display", "block");
                initColorPicker();
            }
            else {
                $("#divMain").css("display", "none");
            }

            function initColorPicker() {
                var offsetTop;
                if ((originObj.offset().top + originObj.height() / 2) < 179) {
                    offsetTop = 0;
                }
                else if ((originObj.offset().top + originObj.height() / 2 + 179) > window.innerHeight) {
                    offsetTop = window.innerHeight - 356;
                }
                else {
                    offsetTop = originObj.offset().top + originObj.height() / 2 - 179;
                }

                var offsetLeft;
                if ((window.innerWidth - originObj.offset().left - originObj.width()) < 325) {
                    offsetLeft = originObj.offset().left - 325;
                }
                else {
                    offsetLeft = originObj.offset().left + originObj.width() + 10;
                }

                $(divMain).css("top", offsetTop);
                $(divMain).css("left", offsetLeft);
            }

            function createElement() {
                divMain = document.createElement("div");
                divMain.id = "divMain";
                $(divMain).css("width", 315).css("height", 356).css("background-color", "#E8E8E8").css("position", "absolute").css("border", "1px solid #CCCCCC").css("-moz-user-select", "none").css("box-shadow", "10px 10px 10px rgba(0, 0, 0, 0.2)").css("display", "none").css("z-index", "10000");

                divHeader = document.createElement("div");
                divHeader.id = "divHeader";
                $(divHeader).css("height", 28).css("background", "-moz-linear-gradient(center top , #FFFFFF, #E5E5E5) repeat scroll 0 0 transparent").css("position", "relative").css("font-weight", 300).css("color", "#212121").css("cursor", "move").css("border-bottom", "1px solid #CCCCCC").css("box-shadow", "0 1px 0 0 #F4F4F4");
                divHeader.onmousedown = divHeaderMouseDown;
                divHeader.onmouseup = divHeaderMouseUp;
                divHeader.onmousemove = divHeaderMouseMove;
                divHeader.onmouseout = divHeaderMouseOut;

                spanName = document.createElement("span");
                spanName.id = "spanName";
                $(spanName).css("height", 28).css("padding-left", 20).css("line-height", "28px").css("text-shadow", "0 1px 0 #FFFFFF").css("background-color", "transparent").css("vertical-align", "top").css("word-wrap", "break-word").css("font-weight", 600).css("font-size", "12px").css("font-family", "HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif").css("float", "left").html("Color");
                spanName.click = cpClose;
                divHeader.appendChild(spanName);

                spanClose = document.createElement("span");
                spanClose.id = "spanClose";
                $(spanClose).css("background", "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAArUlEQVQoz2OYOXMmAxSzAXEOEB8A4p9QfAAqxgZTB1MsDcTngfg/DnweqoYBZvIlPIphGKSGjQFqJUxwPxA7QE1cj8SGyeeANBxGMwmkyACIBYC4AE3uMAPUc8iC9////w8SV8DirJ/YNPSDNEA17UeT+wwSPIZsOtQpDUAcALXlPZL8MZCGfCSB9VDF/6EKG9A8nU9WsMIi7hIBxdLIMQ2zKR+aHODBCBWDJw0AyNRnE3i8MH4AAAAASUVORK5CYII=') no-repeat scroll 0 0 transparent").css("cursor", "pointer").css("height", "12px").css("width", "12px").css("opacity", "0.7").css("overflow", "hidden").css("position", "absolute").css("right", "15px").css("top", "7px").attr("title", "Close");
                spanClose.onclick = cpClose;
                divHeader.appendChild(spanClose);
                $(spanClose).mouseover(function () {
                    $(this).css("opacity", "1");
                });
                $(spanClose).mouseout(function () {
                    $(this).css("opacity", "0.7");
                });
                divMain.appendChild(divHeader);

                divCanvas = document.createElement("div");
                divCanvas.id = "divCanvas";
                $(divCanvas).css("height", 280).css("position", "relative").css("box-shadow", "0 1px 0 0 #F4F4F4").css("border-bottom", "1px solid #CCCCCC");

                divCPSubmit = document.createElement("div");
                divCPSubmit.id = "divCPSubmit";
                $(divCPSubmit).css("height", 40);

                canvasMap = document.createElement("canvas");
                canvasMap.id = "canvasMap";
                contextMap = canvasMap.getContext("2d");
                canvasMap.setAttribute("height", 260);
                canvasMap.setAttribute("width", 260)
                $(canvasMap).css("float", "left").css("position", "absolute").css("top", "10px").css("left", "10px");
                divCanvas.appendChild(canvasMap);

                canvasMapCover = document.createElement("canvas");
                canvasMapCover.id = "canvasMapCover";
                contextMapCover = canvasMapCover.getContext("2d");
                canvasMapCover.setAttribute("height", 260);
                canvasMapCover.setAttribute("width", 260)
                $(canvasMapCover).css("float", "left").css("position", "absolute").css("top", "10px").css("left", "10px").css("cursor", "crosshair").css("background-color", "transparent");
                canvasMapCover.onclick = colorMapClicked;
                divCanvas.appendChild(canvasMapCover);

                canvasMapBar = document.createElement("canvas");
                canvasMapBar.id = "canvasMapBar";
                contextMapBar = canvasMapBar.getContext("2d");
                canvasMapBar.setAttribute("height", 260);
                canvasMapBar.setAttribute("width", 30)
                $(canvasMapBar).css("float", "left").css("position", "absolute").css("top", "10px").css("right", "10px");
                divCanvas.appendChild(canvasMapBar);

                canvasMapBarCover = document.createElement("canvas");
                canvasMapBarCover.id = "canvasMapBarCover";
                contextMapBarCover = canvasMapBarCover.getContext("2d");
                canvasMapBarCover.setAttribute("height", 260);
                canvasMapBarCover.setAttribute("width", 30)
                $(canvasMapBarCover).css("float", "left").css("position", "absolute");
                $(canvasMapBarCover).css("position", "absolute").css("top", "10px").css("right", "10px").css("cursor", "crosshair");
                canvasMapBarCover.onclick = colorMapBarClicked;
                divCanvas.appendChild(canvasMapBarCover);

                divMain.appendChild(divCanvas);

                divFooter = document.createElement("div");
                divFooter.id = "divFooter";
                $(divFooter).css("height", "26px").css("float", "left").css("padding", "10px");

                divApply = document.createElement("div");
                divApply.id = "divApply";
                $(divApply).css("background", "none repeat scroll 0 0 transparent").css("border", "1px solid #CCCCCC").css("font-size", "100%").css("margin", "0px").css("outline", "0 none").css("padding", "0px").css("border-radius", "4px").css("vertical-align", "baseline").css("height", "26px").css("float", "left");

                divColor = document.createElement("div");
                divColor.id = "divColor";
                $(divColor).css("float", "left").css("background-color", "#DB0268").css("height", "13px").css("padding", "6px 5px 7px").css("width", "10px").css("border-radius", "4px 0 0 4px");
                divApply.appendChild(divColor);

                txtColorValue = document.createElement("input");
                txtColorValue.id = "txtColorValue";
                txtColorValue.type = "text";
                $(txtColorValue).css("float", "left").css("box-shadow", "0 -1px 0 0 rgba(255, 255, 255, 0.5) inset, 0 1px 0 rgba(255, 255, 255, 0.5)").css("color", "#444444").css("font-size", "11px").css("padding", "6px 5px 7px").css("width", "50px").css("text-transform", "uppercase").css("text-align", "center").css("border", "0px").css("-moz-user-select", "text");
                txtColorValue.onkeyup = txtColorValueKeyUp;
                divApply.appendChild(txtColorValue);

                btnApply = document.createElement("input");
                btnApply.id = "btnApply";
                btnApply.type = "button";
                $(btnApply).css("background-color", "#DB0268").css("box-shadow", "0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 1px 0 rgba(255, 255, 255, 0.5))").css("border", "0px").css("border-radius", "0px 4px 4px 0px").css("color", "#FFFFFF").css("cursor", "pointer").css("float", "left").css("font-size", "11px").css("padding", "5px 10px 6px 10px").css("text-shadow", "0 -1px 0 rgba(0, 0, 0, 0.5)").attr("value", "Apply");
                btnApply.onclick = cpApply;
                divApply.appendChild(btnApply);

                divFooter.appendChild(divApply);

                btnCancel = document.createElement("input");
                btnCancel.id = "btnCancel";
                btnCancel.type = "button";
                $(btnCancel).css("background-color", "#E5E5E5").css("background-image", "-moz-linear-gradient(center top , #F4F4F4, #E5E5E5)").css("background-repeat", "repeat-x").css("box-shadow", "0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 1px 0 rgba(255, 255, 255, 0.5)").css("border", "1px solid #D1D1D1").css("border-radius", "4px 4px 4px 4px").css("color", "#212121").css("text-shadow", "0 1px 1px rgba(255, 255, 255, 0.75)").css("cursor", "pointer").css("float", "right").css("position", "relative").css("left", "90px").css("margin-bottom", "0px").css("font-size", "11px").css("-moz-user-select", "-moz-none").css("padding", "5px 10px 6px 10px").attr("value", "Cancel");
                btnCancel.onclick = cpClose;
                divApply.appendChild(btnCancel);

                divFooter.appendChild(btnCancel);

                divMain.appendChild(divFooter);

                jQuery("body").prepend(divMain);
                $("#divCPMain").css("display", "block");
            };

            function initColorMapBar() {
                var color = 0;

                var fillColor = contextMapBar.createLinearGradient(1, 1, 30, 1);

                for (var i = 0; i < 6; i++) {
                    color = i % 2 == 0 ? 0 : 255;

                    for (var j = 1; j < 45; j++) {
                        if (i % 2 == 0) {
                            if (color > 248 && color <= 255) {
                                color = 255;
                            }
                            else {
                                color = color + 6;
                            }
                        }
                        else {
                            if (color < 7 && color >= 0) {
                                color = 0;
                            }
                            else {
                                color = color - 6;
                            }
                        }

                        switch (i) {
                            case 0:
                                fillColor.addColorStop(0, "rgba(255,0," + color + ",1)");
                                break;
                            case 1:
                                fillColor.addColorStop(0, "rgba(" + color + ",0,255,1)");
                                break;
                            case 2:
                                fillColor.addColorStop(0, "rgba(0," + color + ",255,1)");
                                break;
                            case 3:
                                fillColor.addColorStop(0, "rgba(0,255," + color + ",1)");
                                break;
                            case 4:
                                fillColor.addColorStop(0, "rgba(" + color + ",255,0,1)");
                                break;
                            case 5:
                                fillColor.addColorStop(0, "rgba(255," + color + ",0,1)");
                                break;
                        }

                        fillColor.addColorStop(1, "rgba(0,0,0,1)");

                        contextMapBar.beginPath();
                        contextMapBar.moveTo(1, j + 43 * i);
                        contextMapBar.lineTo(30, j + 43 * i);
                        contextMapBar.lineWidth = 2;
                        contextMapBar.strokeStyle = fillColor;
                        contextMapBar.stroke();
                    }
                }
            }

            function initColorMap(imageData) {

                var fillColor = contextMapBar.createLinearGradient(1, 1, 1, 260);

                fillColor.addColorStop(1, "rgba(0,0,0,1)");

                for (var i = 0; i < 260; i++) {
                    fillColor.addColorStop(0, "rgba(" + (255 - Math.round((255 - imageData[0]) * i / 260)) + "," + (255 - Math.round((255 - imageData[1]) * i / 260)) + "," + (255 - Math.round((255 - imageData[2]) * i / 260)) + ",1)");

                    contextMap.beginPath();
                    contextMap.moveTo(i + 1, 1);
                    contextMap.lineTo(i + 1, 260);
                    contextMap.lineWidth = 2;
                    contextMap.strokeStyle = fillColor;
                    contextMap.stroke();
                }
            }

            function drawMapCrossMark(coorX, coorY, contextObj) {
                contextObj.clearRect(0, 0, 260, 260);
                contextObj.beginPath();
                contextObj.moveTo(coorX - 4, coorY);
                contextObj.lineTo(coorX - 1, coorY);
                contextObj.moveTo(coorX, coorY - 4);
                contextObj.lineTo(coorX, coorY - 1);
                contextObj.moveTo(coorX + 1, coorY);
                contextObj.lineTo(coorX + 4, coorY);
                contextObj.moveTo(coorX, coorY + 1);
                contextObj.lineTo(coorX, coorY + 4);
                contextObj.lineWidth = 1;
                contextObj.strokeStyle = "#FFF";
                contextObj.stroke();
            }

            function colorMapClicked(e) {
                drawMapCrossMark(e.layerX, e.layerY, contextMapCover);
                var colorData = contextMap.getImageData(e.layerX, e.layerY, 1, 1).data;
                $(txtColorValue).val((colorData[0].toString(16).length == 2 ? colorData[0].toString(16) : "0" + colorData[0].toString(16)) + (colorData[1].toString(16).length == 2 ? colorData[1].toString(16) : "0" + colorData[1].toString(16)) + (colorData[2].toString(16).length == 2 ? colorData[2].toString(16) : "0" + colorData[2].toString(16)));
                $(divColor).css("background-color", "#" + $(txtColorValue).val());
            }

            function colorMapBarClicked(e) {
                drawMapCrossMark(e.layerX, e.layerY, contextMapBarCover);
                var colorData = contextMapBar.getImageData(e.layerX, e.layerY, 1, 1).data;
                initColorMap(colorData);
                $(txtColorValue).val((colorData[0].toString(16).length == 2 ? colorData[0].toString(16) : "0" + colorData[0].toString(16)) + (colorData[1].toString(16).length == 2 ? colorData[1].toString(16) : "0" + colorData[1].toString(16)) + (colorData[2].toString(16).length == 2 ? colorData[2].toString(16) : "0" + colorData[2].toString(16)));
                $(divColor).css("background-color", "#" + $(txtColorValue).val());
            }

            function txtColorValueKeyUp(e) {
                var colorData = $(this).val().split('');

                if (colorData.length >= 3 && colorData.length < 6) {
                    colorData = [colorData[0], colorData[0], colorData[1], colorData[1], colorData[2], colorData[2]];
                }

                var isColorDataIsValid = true;
                for (var i = 0; i < 6; i++) {
                    if (!(colorData[i].charCodeAt() >= 48 && colorData[i].charCodeAt() <= 57) || (colorData[i].charCodeAt() >= 65 && colorData[i].charCodeAt() <= 70) || (colorData[i].charCodeAt() >= 97 && colorData[i].charCodeAt() <= 102)) {
                        isColorDataIsValid = false;
                        break;
                    }
                }
                if (isColorDataIsValid) {
                    $(divColor).css("background-color", "#" + $(txtColorValue).val());
                }
            }

            function divHeaderMouseDown(e) {
                isMouseDown = true;
                layerXTemp = e.layerX;
                layerYTemp = e.layerY;
                $("#divMain").css("opacity", "0.9");
            }

            function divHeaderMouseUp(e) {
                isMouseDown = false;
                $("#divMain").css("opacity", "1");
            }

            function divHeaderMouseMove(e) {
                if (isMouseDown) {
                    $("#divMain").css("left", e.clientX - layerXTemp);
                    $("#divMain").css("top", e.clientY - layerYTemp);
                }
            }

            function divHeaderMouseOut(e) {
                isMouseDown = false;
                $("#divMain").css("opacity", "1");
            }

            function cpApply() {
                if (typeof callbackFun == "function") {
                    if (colorType == "rgb") {
                        callbackFun(new colorRgb($("#divColor").css("background-color").split(')')[0].substring(4).split(',')));
                    }
                    else {
                        callbackFun(colorHex($("#divColor").css("background-color").split(')')[0].substring(4).split(',')).toLocaleUpperCase());
                    }
                }
                $("#divMain").css("display", "none");
            }

            function cpClose() {
                $("#divMain").css("display", "none");
            }

            function colorRgb(rgb) {
                this.r = rgb[0],
                this.g = rgb[1],
                this.b = rgb[2]
            }

            function colorHex(rgb) {
                return "#" + colorSingelHex(parseInt(rgb[0])) + colorSingelHex(parseInt(rgb[1])) + colorSingelHex(parseInt(rgb[2]));
            }

            function colorSingelHex(value) {
                return value.toString(16).length > 1 ? value.toString(16) : "0" + value.toString(16);
            }
        }

    })(jQuery);

  • 相关阅读:
    兼容性问题
    Webfont 的兼容性问题[持续更新]
    WebView的坑[持续更新]
    [转]60fps on the mobile web
    IT男送什么礼物给女朋友呢?
    Lumia 1520 IE mobile window.devicePixelRatio
    Fiddler 故障
    IE(8~11+) 可用右键加速器
    [转]Zen Cart官网屏蔽中国用户访问的真正原因
    Internet Explorer Developer Channel 自动化测试 IE 浏览器
  • 原文地址:https://www.cnblogs.com/brain313001120/p/3076247.html
Copyright © 2011-2022 走看看