2009-11-12 7 views
9

Grundsätzlich verwende ich jQuery ui's selectable Funktionalität auf einem ul, aber die UL wird oft eine Bildlaufleiste haben, und diese Bildlaufleiste wird in Webkit Browsern unbrauchbar, da, wenn Sie versuchen, es zu greifen, das Lasso für die auswählbare Funktionalität wird stattdessen überzeichnet.JQuery UI; Stop Ausbreitung von auswählbaren Ereignissen

Ich habe eine Lösung formuliert, die beinhaltet, die Position des Cursors in Bezug auf die Position und Breite der ul zu überprüfen, ob der Cursor über der Bildlaufleiste ist, und wenn ja, die Ausbreitung des wählbaren 'Start' zu stoppen Ereignis, aber trotz der Bedingung, die erfüllt ist, wenn es sein sollte, weder das Zurückgeben von false noch das Beenden der Ereignisprogression scheint zu verhindern, dass jquery die auswählbaren Ereignisse durchläuft.

Hier ist, was ich für die jquery .selectablestart Veranstaltung:

start: function(event, ui) { 
    var t = event.target; 
    var cutoff = t.scrollWidth + t.offsetLeft 
    if (event.clientX > cutoff) 
    { 
     console.log('NO!'); 
     console.log(event.type); 

     //overkill 
     event.stopPropagation(); 
     event.stopImmediatePropagation(); 

     if (event.stopPropagation) { 
      event.stopPropagation(); 
     } else { 
      event.cancelBubble = true; 
     } 

     return false; 
    } 
} 

Alle Beratung/Lösungen geschätzt, Dank!

+0

wenn Sie sagen, „das Lasso für die wählbare Funktionalität overtop stattdessen gezogen“, was ist das lasso Sie sich beziehen? Kannst du einen Screenshot machen? –

Antwort

14

Das start Ereignis ist ein Tricksy faux one. Sie müssen Ihren Code anfügen, um das Ereignis-Bubbling direkt an das mousedown Ereignis der ul selbst abzubrechen, und sicherstellen, dass Ihr Ereignishandler zuerst ausgeführt wird.

Sie werden für event.stopPropagation diese kleine Zeile in den jQuery docs sehen:

Beachten Sie, dass dies nicht andere Handler auf dem gleichen Element von Laufen verhindern.

So, während event.stopPropagation wird die Veranstaltung sprudeln weiter bis das DOM zu stoppen, es werden die anderen Event-Handler heften sich an die ul dazu aufgerufen, nicht zu stoppen. Dafür brauchen Sie event.stopImmediatePropagation, um den selectable Event-Handler zu stoppen, der angerufen wird.

Basierend auf dem selectable demo page, dieser Code-Schnipsel bricht erfolgreich die Blase:

$(function() { 
    $("#selectable").mousedown(function (evt) { 
     evt.stopImmediatePropagation(); 
     return false; 
    });   
    $("#selectable").selectable(); 
}); 

Beachten Sie, dass Sie Ihre Event-Handler zum ul Objekt vor hinzufügen müssen Sie die .selectable() Setup-Funktion ausführen, um zu schleichen in und platziere die Ereignisblase zuerst.

+3

Gute Analyse. Beachten Sie, dass die Anweisung 'return false' auch' evt.stopPropagation() 'kapselt. IOW du musst nicht unbedingt beides machen. –

+0

Vielen Dank für Ihre Lösung, es macht Sinn, jetzt haben Sie mir erklärt, die Art der. Selectable Events Struktur und die korrekte Verwendung von StopProgation und StopImmediatePropagation und es funktioniert ein Vergnügen! Danke nochmal! – machinemessiah

+0

Ich habe dies an den jQuery-Bug-Tracker gesendet: http://dev.jqueryui.com/ticket/4441 hoffentlich werden sie es beheben. –

1

Sam C's Antwort funktionierte nicht für mich, wahrscheinlich wegen der Art, wie ich #selectable positioniert hatte. Dies ist, was ich verwendet:

$('#selectable') 
    .mousedown(function (evt) { 
    if (event.pageX > $(this).offset().left + $(this).width() - $.getScrollbarWidth()) 
    { 
     evt.stopImmediatePropagation(); 
     return false; 
    } 
    }) 
    .selectable({filter: 'div'}); 

wo $ .getScrollbarWidth() ist von here

2

Hier ist eine leichte Abwandlung Sam C ‚s-Lösung, die besser für mich gearbeitet (nur MouseDown- Ereignis Cancelling wenn es auf dem Element mit dem Scrollbar gefeuert):

$(function() { 
    $("#selectable").mousedown(function (evt) { 
     if ($(evt.originalEvent.target).hasClass('ui-dialog')) // <--- variation 
     { 
      evt.stopImmediatePropagation(); 
      return false; 
     } 
     return true; 
    });   
    $("#selectable").selectable(); 
}); 
+0

Wahrscheinlich meintest du 'if ($ (evt.originalEvent.target) .hasClass ('ui-selectable'))'. Dies ist, was für mich mit einem tbody als der Container (tr waren die ausgewählten) funktioniert. –