iScroll 4无法使用

| 我正在使用以下HTML代码:
<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>
在iPhone和Android上不起作用。当我点击选择框时,没有任何反应。 我正在使用iScroll 4创建问题。
<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>
我认为这是一个解决方案,但我不知道如何实现。     
已邀请:
问题是iScroll取消了
select
标记的默认行为(如果您问我,这不是很好的实现)。 这发生在第195行的
_start()
函数中:
e.preventDefault();
如果您对此发表评论,则会注意到
select
标签再次起作用。 但是将其注释掉意味着您已经破解了该库,这可能会破坏其他所需的iScroll功能。因此,这里有一个更好的解决方法:
var selectField = document.getElementById(\'Field10\');
selectField.addEventListener(\'touchstart\' /*\'mousedown\'*/, function(e) {
    e.stopPropagation();
}, false);
该代码将允许发生默认行为,而无需将事件传播到iScroll,从而将所有事情搞砸了。 由于您的JS不在任何类似jQuery的
onReady()
事件内,因此您必须确保将此代码放在定义
select
元素的HTML之后。 请注意,对于移动设备,该事件是“ 10”,但是对于您的PC浏览器,该事件是“ 11”     
我在Android上的iScroll 4.1.9上遇到了相同的问题,我只是替换了第95行(在我的版本上):
onBeforeScrollStart: function (e) { e.preventDefault(); },
创建人:
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(); },           
可以专注于输入,选择和textarea标签     
最后,针对Android修复了此问题。最终在iscroll.js中修改了几行 这是我们初始化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();
    }
});
onBeforeScrollStart是允许控件的默认行为发生的东西。 Android浏览器似乎对useTransform有问题,因此请转为false。 最后,当useTransform为false时,需要排除一些其他的iscroll代码:
// 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;
在意识到它与iscroll添加的css有关之前,尝试了其他几种方法。     
我知道已经晚了,但是对某些人可能会有所帮助, 在pageshow事件中编写以下代码,但请确保div ID不相同。 这是因为iscroller阻止了元素的默认行为
 $(\'#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);

     });
    
这是解决方案
/* 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);
            }    
        });
    
解决方案的另一个代码示例。并感谢您之前的评论! 使用jQuery! 后:
$(document).ready(function() {            
    document.addEventListener(\'touchmove\', function (e) { e.preventDefault(); }, false);

    document.addEventListener(\'DOMContentLoaded\', setTimeout(function () { loaded(); }, 200), false);
});
在加载功能中
function loaded() {
    var allSelects = $(\'select\');
    allSelects.each(function(index, item) {
                        item.addEventListener(\'touchstart\' /*\'mousedown\'*/, function(e) { e.stopPropagation(); }, false);
                    });
}
    
更换线
onBeforeScrollStart: function (e) { e.preventDefault(); },
通过
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();
    }
},
iScroll.js
作品中     
从此代码开始。此解决方案为我工作:
<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>
    
我迟到了,但我让你解决。 如果您使用的是jQuery,可以尝试一下。
$(\'input, textarea, button, a, select\').off(\'touchstart mousedown\').on(\'touchstart mousedown\', function(e) {
    e.stopPropagation();
});
    
  // 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
  });
对我来说,我只需要在最后一行添加click:true ... 全天都在调试和实施所有建议的解决方案,但无济于事。     
他任何人。 我知道您的所有答案,但是我提供了新的方法。没有Java脚本或drop iscroll函数。 所有此解决方案的最大问题是,当您在input的元素上滚动时,页面上没有滚动。当您仅输入一个或两个输入时并没有什么关系,但是当页面是表单时,滚动页面就会遇到很大的问题。 我提供的解决方案是将输入内容包装在标签标签中,或使标签标签带有指向输入的指针。然后使用绝对定位并在输入上方使用z-index标记。当您触摸标签时,您将聚焦输入。 和例子 的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;}
您还可以通过这种方式将输入的标签面以及输入的绝对位置放入标签区域 正在100%工作,请检查     
将-webkit-transform:translate3d应用于具有选择框或密码框[1]的容器时,Android会出现错误。激活这些元素的框状区域将移动,而不是您认为的位置。此外,密码框在另一个位置绘制,因此看来您有两个输入元素而不是一个。 我在AppMobi工作,我们已经开发了一个工具包库,其中包含针对这些问题的修复程序。我们已经实现了自定义选择框小部件,并替换了密码输入字段。在下面查看。 https://github.com/imaffett/AppMobi.toolkit [1]我认为评论的作者正在谈论此错误https://bugs.webkit.org/show_bug.cgi?id=50552     
我对游戏有点迟了,但是如果仍然有人感兴趣,我会采用@bastien的方法,并对其进行了一些调整,以使其可以在Android上使用。我在实现中使用JQM。 基本上我所做的是:
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);
}

}
基本上,您需要做的就是在用户选择表单元素时销毁iScroll实例,但是在他们真正开始滚动之前(onBeforeScrollStart),并且如果用户单击元素中具有自定义属性
data-iscroll=\"scroller\"
的其他任何内容,他们都可以滚动照常使用iScroll。
<div data-role=\"page\" id=\"pageNameHere\" data-iscroll=\"enable\">
    
这是一个对我有用的非常简单的修复程序。我在Android浏览器中注意到,在初始页面加载时,我无法单击选择框,但可以单击用于搜索的文本输入字段。然后,我注意到在单击文本输入字段后,它将识别出我单击了选择框。所以我所做的就是将其添加到我用来加载搜索页面的javascript函数中...
$(\'#search\').focus();
因此,当加载搜索页面时,它会自动聚焦在文本输入字段上,但不会弹出键盘,这正是我想要的。抱歉,我的示例无法公开访问,但是希望这仍然可以对某人有所帮助。     
试试这个解决方案  如果(e.target.nodeName.toLowerCase()== \“ select \” || e.target.tagName.toLowerCase()== \'input \'|| e.target.tagName.toLowerCase()== \ 'textarea \')             {                 返回;             }     
那对我有用!:
$(\'input, select\').on(\'touchstart\', function(e) {
    e.stopPropagation();
});
    
即使您已经在onBeforeScrollStart()中排除了表单元素,Android 2.2 / 2.3浏览器/ webview中仍然存在另一个错误: https://www.html5dev-software.intel.com/viewtopic.php?f=26&t=1278 https://github.com/01org/appframework/issues/104 您无法使用\“-webkit-transform \\” CSS样式在div的输入元素中输入中文字符。 iscroll 4在滚动条div上应用了“ -webkit-transform”。 解决方案是将表格字段以绝对div形式保持在滚动条之外。     
Android浏览器错误是Android(甚至Android 4.3)内部的WebKit版本过旧导致的。错误的根本原因-iScroll发送回浏览器的click事件处理错误(删除preventDefault只会停止发送此click事件) Android Chrome浏览器无漏洞,因为它已升级了WebKit库。 正在等待从Google升级Android WebKit。     
检查一下。这解决了我的问题 https://github.com/cubiq/iscroll/issues/576 在选项中,我选择了
click:false, preventDefaultException:{tagName:/.*/}
    

要回复问题请先登录注册