wake-up-neo.net

iScroll 4 funktioniert nicht mit dem Formularelement <select> iPhone Safari und dem Android-Browser

Ich verwende diesen HTML-Code:

<form action="#" method="post">
    <fieldset>
        <label class="desc" id="title10" for="Field10">
            How many children do you have?
        </label>        
        <select id="Field10" name="Field10" class="field select large" tabindex="5">
            <option value="0" selected="selected">0 </option>
            <option value="1">1 </option>
            <option value="2">2 </option>
            <option value="3">3 </option>
            <option value="4">4 </option>
            <option value="5">5 </option>
            <option value="6">6 </option>
            <option value="7">7 </option>
            <option value="8">8 </option>
            <option value="9">9 </option>
        </select>
        <input type="submit" value="Send message" />
    </fieldset>
</form>

<select> funktioniert nicht auf iPhone und Android. Wenn ich auf die Auswahlbox tippe, passiert nichts.

Ich verwende iScroll 4, das das Problem verursacht.

<script type="application/javascript" src="iscroll-lite.js"></script>
<script type="text/javascript">
    var myScroll;
    function loaded() {
        myScroll = new iScroll('wrapper');
    }
    document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
    document.addEventListener('DOMContentLoaded', loaded, false);
</script>

Ich denke das ist eine Lösung aber ich weiß nicht, wie ich es umsetzen soll.

26
Jitendra Vyas

Das Problem ist, dass iScroll das Standardverhalten Ihres select-Tags aufhebt (Keine sehr gute Implementierung, wenn Sie mich fragen).

Dies tritt in der Funktion _start() in Zeile 195 auf:

e.preventDefault();

Wenn Sie dies kommentieren, werden Sie feststellen, dass das select-Tag wieder funktioniert.

Wenn Sie es jedoch auskommentieren, haben Sie die Bibliothek gehackt, wodurch andere wünschenswerte iScroll-Funktionen beschädigt werden könnten. Hier ist also eine bessere Lösung:

var selectField = document.getElementById('Field10');
selectField.addEventListener('touchstart' /*'mousedown'*/, function(e) {
    e.stopPropagation();
}, false);

Dieser Code ermöglicht das Auftreten des Standardverhaltens, ohne das Ereignis an iScroll weiterzuleiten, wo alles in Ordnung gebracht wird. 

Da sich Ihr JS nicht in einem jQuery-ähnlichen onReady() -Ereignis befindet, müssen Sie sicherstellen, dass Sie diesen CodeHINTERdem HTML-Code eingeben, in dem Ihre select-Elemente definiert sind. 

Beachten Sie, dass das Ereignis für mobile Geräte touchstart ist, für Ihren PC-Browser jedoch mousedown.

46
sym3tri

Ich hatte das gleiche Problem mit iScroll 4.1.9 unter Android. Ich habe gerade die Linie 95 (bei meiner Version) ersetzt:

onBeforeScrollStart: function (e) { e.preventDefault(); },

durch :

onBeforeScrollStart: function (e) {var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase():(e.target ? e.target.nodeName.toLowerCase():''); if(nodeType !='select' && nodeType !='option' && nodeType !='input' && nodeType!='textarea') e.preventDefault(); },           

, die den Fokus auf Eingabe, Auswahl und Textbereichs-Tags ermöglichen

10
bastien

Endlich behoben für Android. Am Ende ein paar Zeilen in iscroll.js geändert

So initialisieren wir iScroll.

// code from https://github.com/cubiq/iscroll/blob/master/examples/form-fields/index.html
// don't preventDefault for form controls
_menuScroll = new iScroll('menu_wrapper',{
    useTransform: false,
    onBeforeScrollStart: function (e) {
        var target = e.target;
        while (target.nodeType != 1) target = target.parentNode;

        if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA')
        e.preventDefault();
    }
});

Mit onBeforeScrollStart können die Standardverhalten der Steuerelemente ausgeführt werden. Der Android-Browser scheint ein Problem mit useTransform zu haben. 

Schließlich musste zusätzlicher iscroll-Code ausgeschlossen werden, wenn useTransform false ist:

// iscroll.js v4.1.9
// line 216:
if (that.options.useTransform) bar.style.cssText += ';pointer-events:none;-' + vendor + '-transition-property:-' + vendor + '-transform;-' + vendor + '-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-' + vendor + '-transition-duration:0;-' + vendor + '-transform:' + trnOpen + '0,0' + trnClose;

// line 295:
if (that.options.useTransform) that[dir + 'ScrollbarIndicator'].style[vendor + 'Transform'] = trnOpen + (dir == 'h' ? pos + 'px,0' : '0,' + pos + 'px') + trnClose;

Ich habe einige andere Methoden ausprobiert, bevor er merkte, dass es mit der von iscroll hinzugefügten CSS zu tun hatte.

6
deCastongrene

Ich weiß, ich bin spät dran, aber es könnte für jemanden hilfreich sein,

schreiben Sie den folgenden Code in das pageshow -Ereignis. Stellen Sie jedoch sicher, dass die Div-IDs nicht identisch sind.

dies liegt daran, dass iscroller das Standardverhalten von Elementen verhindert

 $('#yourpage').bind('pageshow',function (event, ui) {

       var myScroll;

         if (this.id in myScroll) {
         myScroll[this.id].refresh();

         }else{ 

          myScroll[this.id] = new iScroll('wrapper', { //wrapper is div id
                   checkDOMChanges: true,
                   onBeforeScrollStart: function (e) {
                         var target = e.target;
                         while (target.nodeType != 1) 
                         target =target.parentNode;

                   if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA'){  e.preventDefault();  }
                                 }
                               });
                            }
     document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

     });
4
Mallikarjun

Hier ist die Lösung

/* on page add this after all scripts */
    <script type="text/javascript">
            var myScroll;
            function loaded() {
                myScroll = new iScroll('wrapper');
            }
            document.addEventListener('DOMContentLoaded', function(){ setTimeout(loaded,500);}, false);
    </script>

/* attach a script for fix */
        $(document).ready(function(){
            var my_select = document.getElementsByTagName('select');
            for (var i=0; i<my_select.length; i++) {
                my_select[i].addEventListener('touchstart' /*'mousedown'*/, function(e) {
                    myScroll.destroy();
                    setTimeout(function(){myScroll = new iScroll('wrapper');},500);
                }, false);
            }

    /*if you have input problems */

            var input = document.getElementById('input');

            if (input) {
                input.addEventListener('touchstart' /*'mousedown'*/, function(e) {
                    e.stopPropagation();
                }, false);
            }    
        });
3
comonitos

Beginnen Sie mit diesem Code. Diese Lösung hat für mich funktioniert:

<script type="text/javascript">

var myScroll;
function iScrollLoad() {
    myScroll = new iScroll('wrapper');
    enableFormsInIscroll();
}

function enableFormsInIscroll(){
  [].slice.call(document.querySelectorAll('input, select, button, textarea')).forEach(function(el){
    el.addEventListener(('ontouchstart' in window)?'touchstart':'mousedown', function(e){
      e.stopPropagation();
    })
  })
}

document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function () { setTimeout(iScrollLoad, 200); }, false);

</script>
2
Joe L.

Zeile ersetzen, onBeforeScrollStart: function (e) { e.preventDefault(); },

Durch

onBeforeScrollStart: function (e) {
    var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase():(e.target ? e.target.nodeName.toLowerCase():'');

    if(nodeType !='select' && nodeType !='option' && nodeType !='input' && nodeType!='textarea') {
         e.preventDefault();
    }
},

In iScroll.js Works

2
Sunil P

ein weiteres Codebeispiel für die Lösung. und vielen Dank für die vorherigen Kommentare! Jquery verwenden!

Nach dem:

$(document).ready(function() {            
    document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

    document.addEventListener('DOMContentLoaded', setTimeout(function () { loaded(); }, 200), false);
});

in geladener Funktion

function loaded() {
    var allSelects = $('select');
    allSelects.each(function(index, item) {
                        item.addEventListener('touchstart' /*'mousedown'*/, function(e) { e.stopPropagation(); }, false);
                    });
}
2
tapin13

Ich bin spät dran, aber ich lasse dir meine Lösung.

Wenn Sie jQuery verwenden, können Sie das versuchen.

$('input, textarea, button, a, select').off('touchstart mousedown').on('touchstart mousedown', function(e) {
    e.stopPropagation();
});

er irgendjemand.

ich weiß über alle Ihre Antworten Bescheid, aber ich habe einen neuen Weg anzubieten. ohne Java-Script oder Drop-Iscroll-Funktionen.

das große Problem bei all dieser Lösung besteht darin, dass Sie beim Blättern auf dem Eingabeelement keinen Bildlauf auf der Seite durchführen. Wenn Sie nur eine oder zwei Eingaben machen, spielt das keine Rolle, aber wenn die Seite ein Formular ist, haben Sie ein großes Problem beim Scrollen der Seite.

die Lösung, die ich anbiete, ist, die Eingabe in ein Label-Tag einzuwickeln oder das Label-Tag mit für Zeiger auf die Eingabe zu erstellen. dann machen Sie mit absoluter Positionierung und z-Index die Beschriftung über der Eingabe. Wenn Sie auf das Etikett tippen, fokussieren Sie die Eingabe.

und Beispiel bitte

HTML

<fieldset>
<label>
    <input type="text" />
</label>
</fieldset>

CSS

fieldset {position:relative;z-index:20;}
label {position:relative;z-index:initial;}
input {position:relative;z-index:-1;}

sie können auf diese Weise auch die Beschriftungsseite der Eingabe und mit der Position absolut der Eingabe in den Beschriftungsbereich einfügen

funktioniert in 100%, überprüfen Sie es

1
g.e.manor
  // Setup myScroll
  myScroll = new IScroll('#wrapper', {
    scrollX: horizontalSwipe,
    scrollY: !horizontalSwipe,
    momentum: false,
    snap: document.querySelectorAll('#scroller .slide'),
    snapSpeed: 400,
    bounceEasing: 'back',
    keyBindings: true,
    click: true
  });

Für mich muss ich nur click: true in der letzten Zeile hinzufügen ... Ich habe den ganzen Tag mit Debuggen und Implementieren aller vorgeschlagenen Lösungen ohne Erfolg verbracht ...

1
Zennichimaro

Selbst wenn Sie Formularelemente in onBeforeScrollStart () ausgeschlossen haben, gibt es einen weiteren Fehler in Android 2.2/2.3 Browser/Webview:

https://www.html5dev-software.intel.com/viewtopic.php?f=26&t=1278https://github.com/01org/appframework/issues/104

Sie können keine chinesischen Zeichen in Eingabeelemente im div mit dem CSS-Stil "-webkit-transform" eingeben. Der iscroll 4 hat die "-webkit-transform" mit dem Scroller div angewendet.

Die Lösung besteht darin, Formularfelder in einem absoluten Div außerhalb des Scrollers zu halten.

0
diyism

Android-Browser-Fehler sind das Ergebnis einer sehr alten Version von WebKit in Android, sogar in Android 4.3. Die Hauptursache für Fehler - Falsche Verarbeitung des Klickereignisses, das iScroll an den Browser zurücksendet (das Entfernen von reflectDefault stoppt das Senden dieses Klickereignisses.) Der Browser Chrome Chrome ist von diesem Fehler befreit, da die WebKit-Bibliothek darin aktualisiert wurde.

Warten auf Android WebKit-Aktualisierung von Google.

0
Anatoliy Shuba

versuchen Sie diese Lösung if (e.target.nodeName.toLowerCase () == "select" || e.target.tagName.toLowerCase () == 'input' || e.target.tagName.toLowerCase () == 'textarea') __. {
Rückkehr; }

0
Sukesh Marla

Hier ist eine wirklich einfache Lösung, die für mich funktioniert hat. In den Android-Browsern ist mir aufgefallen, dass ich beim ersten Laden der Seite nicht auf ein Auswahlfeld klicken konnte, aber ich konnte auf ein Texteingabefeld klicken, das ich für die Suche verwendete. Dann bemerkte ich, dass ich nach dem Klicken auf das Texteingabefeld erkannte, dass ich auf ein Auswahlfeld klickte. Also alles, was ich tat, war dies der Javascript-Funktion hinzuzufügen, mit der ich die Suchseite geladen habe ...

$('#search').focus();

Wenn die Suchseite geladen wird, fokussiert sie automatisch auf das Texteingabefeld, öffnet jedoch nicht die Tastatur. Genau das wollte ich. Entschuldigung, mein Beispiel ist nicht öffentlich zugänglich, aber hoffentlich kann dies trotzdem jemandem helfen.

0
Pete

Überprüfen Sie dies. Dies hat mein Problem behoben

https://github.com/cubiq/iscroll/issues/576

In Option habe ich ausgewählt

click:false, preventDefaultException:{tagName:/.*/}
0
A Paul

Ich bin ein bisschen spät im Spiel, aber wenn noch jemand interessiert ist, habe ich @ bastiens Herangehen genommen und es ein bisschen angepasst, damit es auf Android funktioniert. Ich verwende JQM für meine Implementierung.

Im Grunde habe ich Folgendes getan: 

function scrollMe(element) {

var contentID = $wrapper.get(0).id;
var scroller = Elm.find('[data-iscroll="scroller"]').get(0);
if (scroller) {
    var iscroll = new iScroll(contentID, {
        hScroll        : false,
        vScroll        : true,
        hScrollbar     : false,
        vScrollbar     : true,
        fixedScrollbar : true,
        fadeScrollbar  : false,
        hideScrollbar  : false,
        bounce         : true,
        momentum       : true,
        lockDirection  : true,
        useTransition  : true, 
        //the preceding options and their values do not have any to do with the fix
        //THE FIX:
        onBeforeScrollStart: function(e) {
            var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase() : (e.target ? e.target.nodeName.toLowerCase():''); //get element node type
            if(nodeType !='select' && nodeType !='option' && nodeType !='input' && nodeType!='textarea') e.preventDefault(); //be have normally if clicked element is not a select, option, input, or textarea.
            else if (iscroll != null) {   //makes sure there is an instance to destory
                     iscroll.destroy(); 
                     iscroll = null;
            //when the user clicks on a form element, my previously instanced iscroll element is destroyed
            }
        },
        onScrollStart: function(e) { 
            if (iscroll == null) {  //check to see if iscroll instance was previously destoryed 
                var Elm = $.mobile.activePage; //gets current active page
                var scrollIt = setTimeout( function(){ scrollMe(Elm) }, 0 ); 
            } //recursively call function that re-instances iscroll element, as long as the user doesn't click on a form element
        } 
    });
    Elm.data("iscroll-plugin", iscroll);
}

}

Sie müssen im Grunde nur Ihre iScroll-Instanz zerstören, wenn ein Formularelement vom Benutzer ausgewählt wird, aber bevor der Bildlauf tatsächlich gestartet wird (onBeforeScrollStart) und wenn der Benutzer innerhalb des Elements mit dem benutzerdefinierten Attribut data-iscroll="scroller" auf irgendetwas anderes klickt, können Sie einen Bildlauf durchführen Verwendung von iScroll wie gewohnt.

<div data-role="page" id="pageNameHere" data-iscroll="enable">
0
Krazer

Bei Android gibt es einen Fehler, wenn -webkit-transform: translate3d auf einen Container angewendet wird, der über ein Auswahlfeld oder ein Kennwortfeld verfügt [1]. Der geschachtelte Bereich, in dem diese Elemente aktiviert werden sollen, wird verschoben, und Sie befinden sich nicht dort, wo Sie sie für wahrscheinlich halten. Darüber hinaus werden die Kennwortfelder an einem anderen Ort gemalt. Es scheint also, als hätten Sie zwei Eingabeelemente anstelle von einem.

Ich arbeite bei AppMobi und wir haben eine Toolkit-Bibliothek entwickelt, die Korrekturen für diese enthält. Wir haben benutzerdefinierte Auswahlfeld-Widgets und einen Ersatz für das Kennworteingabefeld implementiert. Schau es dir unten an.

https://github.com/imaffett/AppMobi.toolkit

Ich denke, der Autor des Kommentars spricht über diesen Fehler https://bugs.webkit.org/show_bug.cgi?id=50552

0
user258082

Was ist, das funktioniert für mich !:

$('input, select').on('touchstart', function(e) {
    e.stopPropagation();
});
0
pkdkk