Javascript / jQuery - Почему это событие endDrag не запускается должным образом? - PullRequest
0 голосов
/ 15 февраля 2012

В следующем элементе управления расширенного редактирования (CLEditor, доступен здесь ) захват для перетаскивания в нижней части поля позволяет мне перетаскивать вниз и отпускать в порядке, перетаскивать вниз и вверх и отпускать в порядке, но перетаскивая вверх заставляет его никогда не запускать событие endDrag, и мне пришлось реализовать тайм-аут kludge. Вы знаете, что я могу делать неправильно в jQuery / Javascript?

Примечание. Я создал пример для jsFiddle здесь .

<script type="text/javascript">
var textarea, staticOffset;
var iLastMousePos = 0;
var iMin = 160;
var prevTimeout = null;

function startDrag(e) {
    console.log('startDrag() event fired');
    textarea = $(e.data.el);
    textarea.blur();
    iLastMousePos = mousePosition(e).y;
    staticOffset = textarea.height() - iLastMousePos;
    textarea.css('opacity', 0.25);
    $(document).mousemove(performDrag).mouseup(endDrag);
    return false;
}

function performDrag(e) {
    console.log('performDrag() event fired');
    var iThisMousePos = mousePosition(e).y;
    var iMousePos = staticOffset + iThisMousePos;

    // kludge start
    // Try implementing without this and the endDrag event won't fire
    // if you immediately start dragging upwards
    if (iLastMousePos >= (iThisMousePos)) {
        console.log('kludge implemented');
        iMousePos -= 60;
        if (iMousePos < iMin) {
            endDrag();
            return false;
        }
        if (!prevTimeout) {
            prevTimeout = setTimeout('endDrag();clearTimeout();',600);
        }
    }
    // end kludge

    iLastMousePos = iThisMousePos;
    iMousePos = Math.max(iMin, iMousePos);
    textarea.height(iMousePos + 'px');
    if (iMousePos < iMin) {
        endDrag();
    }
    return false;
}

function endDrag() {
    console.log('endDrag() event fired');
    prevTimeout = null;
    $(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag);
    textarea = $('.cleditorMain:first'); // got a better selector?
    textarea.css('opacity', 1);
    textarea.focus();
    textarea = null;
    staticOffset = null;
    iLastMousePos = 0;
    var editor = $("#fldMessage").cleditor()[0];
    editor.refresh();
    if (!$.browser.msie) { // there's a quirk in IE
        editor.focus();
    }   
}

function mousePosition(e) {
    return { x: e.clientX + document.documentElement.scrollLeft, y: e.clientY + document.documentElement.scrollTop };
};

$(document).ready(function(){

    $('#fldMessage').cleditor({
        width:'100%',
        height:'100%',
        useCSS:true,
        styles:[["Paragraph", "<p>"], ["Header 1", "<h1>"], ["Header 2", "<h2>"],
               ["Header 3", "<h3>"],  ["Header 4","<h4>"],  ["Header 5","<h5>"],
               ["Header 6","<h6>"],  ["Code","<pre>"]],
        docCSSFile:"js/jquery.cleditor/jquery.cleditor.doc.css"
    }).focus(); 

    // BTW, if you have a more efficient selector than .cleditorMain:first, please let me know
    $('.cleditorMain:first').after('<div class="gripper" />');
    $('.cleditorMain:first').next('.gripper').css({
                'background':'transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAFCAMAAACD1meMAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAGUExURbu7u////3iwjPUAAAACdFJOU/8A5bcwSgAAABRJREFUeNpiYMADGHEDBhroAwgwAA9QADeT0qnSAAAAAElFTkSuQmCC) no-repeat scroll center 2px',
                'cursor':'s-resize',
                'height':'9px',
                'overflow':'hidden'
    }).bind("mousedown",{el: $('.cleditorMain:first')} , startDrag);

});
</script>

<fieldset style="min-height:160px">
    <textarea id="fldMessage" name="fldMessage" rows="4"></textarea>
</fieldset>

Ответы [ 2 ]

0 голосов
/ 16 февраля 2012

Я нашел ответ, и это время - браузер извращен во всех браузерах. Я также использовал пересмотренный пример примерно так:

http://jsfiddle.net/bCBRW/

<script type="text/javascript">
var textarea, staticOffset;
var iLastMousePos = 0;
var iMin = 160;

function startDrag(e) {
    textarea = $(e.data.el);
    textarea.blur();
    iLastMousePos = mousePosition(e).y;
    staticOffset = textarea.height() - iLastMousePos;
    $(document).mousemove(performDrag).mouseup(endDrag);
    return false;
}

function performDrag(e) {
    var iThisMousePos = mousePosition(e).y;
    var iMousePos = staticOffset + iThisMousePos;

    if (iLastMousePos >= (iThisMousePos)) {
        iMousePos -= 4;
    }

    iLastMousePos = iThisMousePos;
    iMousePos = Math.max(iMin, iMousePos);
    textarea.height(iMousePos + 'px');
    if (iMousePos < iMin) {
        endDrag();
    }
    return false;
}

function endDrag() {
    $(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag);
    textarea = $('.cleditorMain:first');
    textarea.focus();
    textarea = null;
    staticOffset = null;
    iLastMousePos = 0;
    var editor = $("#fldMessage").cleditor()[0];
    editor.refresh();
    if (!$.browser.msie) {
        editor.focus();
    }
}

function mousePosition(e) {
    return {
        x: e.clientX + document.documentElement.scrollLeft,
        y: e.clientY + document.documentElement.scrollTop
    };
};

$(document).ready(function() {
    $('#fldMessage').cleditor({
        width: '99%',
        height: '100%',
        useCSS: true,
        styles: [["Paragraph", "<p>"], ["Header 1", "<h1>"], ["Header 2", "<h2>"],
                           ["Header 3", "<h3>"], ["Header 4", "<h4>"], ["Header 5", "<h5>"],
                           ["Header 6", "<h6>"], ["Code", "<pre>"]],
    }).focus();

    $('.cleditorMain:first').after('<div class="gripper" />');
    $('.cleditorMain:first').next('.gripper').css({
        'background': 'transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAFCAMAAACD1meMAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAGUExURbu7u////3iwjPUAAAACdFJOU/8A5bcwSgAAABRJREFUeNpiYMADGHEDBhroAwgwAA9QADeT0qnSAAAAAElFTkSuQmCC) no-repeat scroll center 2px',
        'cursor': 's-resize',
        'height': '9px',
        'overflow': 'hidden'
    }).bind("mousedown", {
        el: $('.cleditorMain:first')
    }, startDrag);
});​

Так или иначе, это время. Я попробовал совершенно отдельный многофункциональный элемент управления редактора и обнаружил, что браузер не может поддерживать (даже Google Chrome), когда вы изменяете размер элемента управления richedit (который в основном использует IFRAME). Если вы изменяете размер вверх достаточно быстро, ваша мышь движется вперед слишком быстро и endDrag () никогда не срабатывает. Это просто причуда браузера с событиями перетаскивания в браузере.

Если вы двигаете мышь медленнее, проблема исчезнет. Проблема в том, что событие mousemove теряется при перемещении фокуса в IFRAME.

0 голосов
/ 15 февраля 2012

Я мог бы неправильно понять вопрос, но если проблема в том, что перетаскивание вверх, чтобы получить размер <160, на самом деле никогда не вызывает торможение конца; проблема заключается в приведенном ниже утверждении if. </p>

iLastMousePos = iThisMousePos;
iMousePos = Math.max(iMin, iMousePos);
textarea.height(iMousePos + 'px');
if (iMousePos < iMin) {
    endDrag();
}

Math.max лишил iMousePos возможности быть

Это на самом деле одна проблема; но это не основная проблема, которую вы ищете. Кажется, проблема, которую я вижу, связана с маскировкой событий. Это происходит, даже если вы тянете вниз, а затем назад; Вы потеряете событие перемещения мыши. Поскольку возможно обновление, когда положение мыши изменяется не более чем на 1 пиксель, возможно, что событие mousedown теряется, когда мышь выходит из области .gripper и попадает в область текста. Я посмотрю, когда у меня будет больше времени и я буду обновляться; но есть решение, так как это было сделано здесь на SO, если вы редактируете комментарий. Скорее всего, это будет что-то вроде установки события mousemove для документа на глобальном уровне, а затем создания глобального объекта, в котором указано, перетаскиваете ли вы или нет. Затем происходит mousedown / mouseup и задает глобальную переменную перетаскивания, чтобы метод move работал.

...