Closed mrmikeeu closed 10 years ago
Wie lässt sich das in der Onlinedemo reproduzieren?
Versuche CSS zu bearbeiten, zum Beispiel hintergrundfarbe von body tag: color picker geht nicht.
In Artikel kann ich die Elemente nicht verschieben (in Home zum beispiel)
Keine JS Fehler, Keine Add-ons/Plugins. Saubere Chrome installation.
Kann ich nicht reproduzieren.
Ich kann es ebenfalls nicht reproduzieren. Zumindest nicht in den mir vorliegenden Betriebssystemen; Windows 8 verwende ich nicht. Kann mir aber auch nicht vorstellen, dass es BS-spezifisch ist.
Es gibt andere Meldungen auf das Forum. Habe es auf zwei Windows 8 Systeme. Nur in Chrome. Firefox ist OK.
Korrektur: auch Opera geht nicht (auch Webkit). Safari geht aber (anderen Fork von Webkit).
Ich nehme an es ist ein bestimmtes Webkit Fork Thema.
Ich kann es Reproduzieren.
Browser: Chrome (Canary)
Keine Javascript-Fehler in der JS-Konsole.
Toll, ich kann es nicht reproduzieren. Weder auf Win 8 noch auf 8.1. Genau die gleiche Version von Chrome und Contao. ^^
Okay... ich teste mal ein paar Browser durch. In den angehakten Browsern klappt alles:
Nachtrag: Der Test lief auf der Online-Demo.
Kann bestätigen dass es da Probleme gibt. Hatte mal den Cache und die Einstellungen zurückgesetzt (im Chrome), dann gings wieder. Paar Wochen später wieder nicht... Chrome Bug ;)
Ich kann das Problem reproduzieren. Mit Chrome 32 (beta) und 33 (dev) funktioniert Drag&Drop nicht.
Das Problem liegt daran, das Chrome ab Version 32 auf Windows 8 denkt, dass Touch-Support vorhanden ist. Das führt zum Problem mit folgender Routines in der assets/contao/core.js
// Map the touch events to mouse events on mobile devices
if (Browser.Features.Touch) (function() {
delete Element.NativeEvents['mousedown'];
Element.defineCustomEvent('mousedown', { base:'touchstart' });
delete Element.NativeEvents['mousemove'];
Element.defineCustomEvent('mousemove', { base:'touchmove' });
delete Element.NativeEvents['mouseup'];
Element.defineCustomEvent('mouseup', { base:'touchend' });
})();
Die Touch-Events werden dabei auf Mouse-Events umgemünzt. Durch deaktivierung dieser Routine geht das Drag&Drop wieder (was natürlich keine Lösung ist). Der nächste Schritt wäre wohl zu testen, ob auf normalen Touch-Geräten ein Mouse-Event verfügbar ist, um nur im Negativfall auch die Verknüpfung herzustellen.
Ich hatte gerade noch eine Erkenntnis. Durch das Mapping der Events werden die nativen Mouse-Event "gekillt", weshalb natürlich nichts mehr geht. Dass Touch-Events verfügbar sind, bedeutet ja nicht dass keine Mouse-Events mehr benötigt werden (denn moderne Laptops haben teilweise beides).
Ein schön ausführlicher Artikel zum Thema hab ich hier gefunden: http://www.html5rocks.com/en/mobile/touchandmouse/
PS: wir konnten das Problem in Chrome 32/33 wohl nur reproduzieren, weil die Beta-Version standardmässig Touch-Support anbietet (auch wenn die Platform das nicht kann). Im initialen Ticket stand ja Chrome 31 auf Windows 8, ich gehe mal davon aus @mhenke64 hat ein Gerät mit Touch-Support und Maus?
Genau, laptop mit touch screen und maus.
Das Ersetzen der Mouse-Events stammt aus MooTools-Mobile: https://github.com/cpojer/mootools-mobile/blob/master/Source/Touch/Click.js
@mhenke64 kannst du bitte mal http://jsfiddle.net/5jgSF/ auf deinem Laptop testen? Welche Ausgabe (im schwarzen Bereich) bekommst du, wenn du einmal mit Maus und einmal per Finger auf den "Hier klicken" Bereich klickst/touchst?
Ich habe Win 8.1, Touchscreen, Chrome 31.0.1650.57 m. Das Reihenfolge-Ändern geht im Chrome bei mir nicht. Bei dem jsfiddle kommt für Maus und Touch diesselbe Ausgabe, mousedown mouseup
Es erscheint keine touchstart
und touchend
Meldung?
Nope, kein touchstart / end
Maus:
Touch:
Schade, war ja klar das es nicht so einfach ist :D
Könnte man das Problem nicht durch ein Verschieben des Threads lösen? Von hier in die Issue List vom Chrome? :-)
Das ist kein Issue von Chrome, sondern von Contao.
@aschempp Noch andere Ideen, wie man das Problem in den Griff bekommen könnte?
ja, aber noch nichts gemacht :(
So, jetzt kümmere ich mich drum :-)
So, ich habe die Lösung. Wir können (voraussichtlich) nicht einfach die Touch- auf Mouse-Events ummünzen, sondern explizit Touch-Support für MooTools.Sortables + Mootools.Drag einbauen.
Basierend auf der Vorlage von http://stackoverflow.com/questions/7588576/drag-with-mootools-on-mobile habe ich eine Lösung gefunden, welche für meinen Fall mit Chrome Emulated-Touch und auch auf meinem iPhone funktioniert. Die problematische Routine in der contao.js
muss durch folgenden Code ersetzt werden:
Class.refactor(Drag,
{
attach: function(){
this.handles.addEvent('touchstart', this.bound.start);
return this.previous.apply(this, arguments);
},
detach: function(){
this.handles.removeEvent('touchstart', this.bound.start);
return this.previous.apply(this, arguments);
},
start: function(event){
document.addEvents({
touchmove: this.bound.check,
touchend: this.bound.cancel
});
this.previous.apply(this, arguments);
},
check: function(event){
if (this.options.preventDefault) event.preventDefault();
var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
if (distance > this.options.snap){
this.cancel();
this.document.addEvents({
mousemove: this.bound.drag,
mouseup: this.bound.stop
});
document.addEvents({
touchmove: this.bound.drag,
touchend: this.bound.stop
});
this.fireEvent('start', [this.element, event]).fireEvent('snap', this.element);
}
},
cancel: function(event){
document.removeEvents({
touchmove: this.bound.check,
touchend: this.bound.cancel
});
return this.previous.apply(this, arguments);
},
stop: function(event){
document.removeEvents({
touchmove: this.bound.drag,
touchend: this.bound.stop
});
return this.previous.apply(this, arguments);
}
});
Class.refactor(Sortables,
{
initialize: function(lists, options){
options.dragOptions = Object.merge(options.dragOptions || {}, { preventDefault: (options.dragOptions && options.dragOptions.preventDefault) || Browser.Features.Touch });
return this.previous.apply(this, arguments);
},
addItems: function(){
Array.flatten(arguments).each(function(element){
this.elements.push(element);
var start = element.retrieve('sortables:start', function(event){
this.start.call(this, event, element);
}.bind(this));
(this.options.handle ? element.getElement(this.options.handle) || element : element).addEvents({
mousedown: start,
touchstart: start
});
}, this);
return this;
},
removeItems: function(){
return $$(Array.flatten(arguments).map(function(element){
this.elements.erase(element);
var start = element.retrieve('sortables:start');
(this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvents({
mousedown: start,
touchend: start
});
return element;
}, this));
},
getClone: function(event, element){
if (!this.options.clone) return new Element(element.tagName).inject(document.body);
if (typeOf(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list);
var clone = this.previous.apply(this, arguments);
clone.addEvent('touchstart', function(event){
element.fireEvent('touchstart', event);
});
return clone;
}
});
Es stellt sich nun lediglich die Frage, ob dies in die contao.js
gehört oder besser gleich in die mootools.js
gepackt werden sollte, damit die Funktion auch im Frontend zur Verfügung steht?
Implementiert in ecedc88a0cd5bb608dcbddff1af006b6ab4c492c. Hab es in die "MooTao"-Klasse eingefügt, in der schon andere Contao-spezifische MooTools-Anpassungen enthalten sind :)
@aschempp Bin immer wieder beeindruckt von Deinen JavaScript-Kenntnissen!
Danke :-)
Win 8, Chrome Version 31.0.1650.57 m, Contao 3.2.1
Kein drag/drop im Backend, zum Beispiel color picker, Reihenfolge, etc.