0

我发现 flexi 颜色选择器脚本可以为您提供基于纯 JavaScript 的颜色选择,但是它不允许拖动进行选择,只能单击调色板。

我从以下方面做了很少的修复:

if (slideElement.attachEvent) {
    slideElement.attachEvent('onclick', slideListener(this, slideElement, pickerElement));
    pickerElement.attachEvent('onclick', pickerListener(this, pickerElement));
} else if (slideElement.addEventListener) {
    slideElement.addEventListener('click', slideListener(this, slideElement, pickerElement), false);
    pickerElement.addEventListener('click', pickerListener(this, pickerElement), false);
}

if (slideElement.attachEvent) {
    slideElement.attachEvent('onmouseup', slideListener(this, slideElement, pickerElement));
    slideElement.attachEvent('onmousedown', slideListener(this, slideElement, pickerElement));

    pickerElement.attachEvent('onmouseup', pickerListener(this, pickerElement));
    pickerElement.attachEvent('onmousedown', pickerListener(this, pickerElement));
} else if (slideElement.addEventListener) {
    slideElement.addEventListener('mouseup', slideListener(this, slideElement, pickerElement), false);
    slideElement.addEventListener('mousedown', slideListener(this, slideElement, pickerElement), false);

    pickerElement.addEventListener('mouseup', pickerListener(this, pickerElement), false);
    pickerElement.addEventListener('mousedown', pickerListener(this, pickerElement), false);
}

它有效,但是只有在页面加载时才有效,如果你不止一次开始拖动背景图像,有没有办法解决这个问题?

另外可选的事情是让它改变颜色,同时按住鼠标按钮并尽可能拖动鼠标。

http://jsfiddle.net/NkH3q/

4

1 回答 1

1

你在这里http://jsfiddle.net/NkH3q/3/

(不适用于 IE8 < 因为我没有 IE 来测试它,但您应该能够复制 IE 的处理程序,它应该可以正常工作)。

解释。

你所追求的是让选择器仅在鼠标按下时移动/拖动。为此,您需要在mousedown上添加一个侦听器

Elem.addEventListener('mousedown', startDragging, false);

您注意到我们还没有为mouseup事件添加监听器,我们现在也不会。startDragging 函数只是设置一个标志

this.dragging = false;
var q = this; // cache this to use it in another function scope

var startDragging = function() {
  q.dragging = true;  
  document.addEventListener('mouseup', stopDragging , false);
};

一切都应该很清楚。您会注意到我们在文档中设置了mouseup侦听器。这样做是为了确保即使用户将光标移出颜色选择器,当点击被释放(mouseup)时,事件也会被我们捕获。

让我们看看stopDragging函数应该是什么样子

    var stopDragging = function() {
      q.dragging = false;  
      document.removeEventListener('mouseup', stopDragging , false);
    };

同样,我们将拖动标志设置为 false,并删除我们在文档中设置的mouseup侦听器。毕竟,我们不想把 memm 乱扔给听众。

现在是mousemove函数

var pickerFunc = pickerListener(this, pickerElement ),
    slideFunc = slideListener(this, slideElement, pickerElement);

slideElement.addEventListener('mousemove', slideFunc, false);
pickerElement.addEventListener('mousemove',pickerFunc, false);

....
function pickerListener(ctx, pickerElement) {
    return function(evt) {
        if (!ctx.dragging)   
          return false;
.....

首先,既然 pickerListener/slideListener 返回函数,就不需要多次调用它们,只要我们每次都使用相同的参数。因为我们最终会得到重复的函数。因此最好这样做一次并缓存它们(slideFunc/pickerFunc vars)

然后在这些函数的开头,我们添加了对拖动标志的检查。如果它设置为 false,我们什么也不做。

为了防止东西被选中并破坏“拖动”控件,我们需要添加

-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none; 
-ms-user-select: none;
user-select: none; 

在包装元素。旧版本的 IE (7,8,9) 和 Opera 需要在 wrapper 元素上有一个unselectable="on" 属性。

于 2012-10-19T23:09:34.123 回答