19 に答える
問題は、iScroll がselect
タグのデフォルトの動作をキャンセルすることです (私に言わせれば、あまり良い実装ではありません)。
これは、_start()
195 行目の関数で発生します。
e.preventDefault();
それをコメントアウトすると、select
タグが再び機能することに気付くでしょう。
しかし、それをコメントアウトするということは、他の望ましい iScroll 機能を壊す可能性のあるライブラリをハッキングしたことを意味します。したがって、より良い回避策は次のとおりです。
var selectField = document.getElementById('Field10');
selectField.addEventListener('touchstart' /*'mousedown'*/, function(e) {
e.stopPropagation();
}, false);
そのコードにより、イベントが iScroll に伝播されてすべてが台無しになることなく、デフォルトの動作が発生することが許可されます。
JS は jQuery のようなイベント内にないため、要素が定義されているHTMLonReady()
の後にこのコードを配置する必要があります。select
モバイル デバイスの場合、イベントは ですtouchstart
が、PC ブラウザーの場合は になります。mousedown
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(); },
input、select、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);
}
});
ラインの交換、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
作品中
ソリューションの別のコード例。そして以前のコメントありがとう!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);
});
}
このコードから始めます。この解決策は私のために働いた:
<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();
});
彼は誰でも。
私はあなたのすべての答えについて知っていますが、提供する新しい方法があります。java-script または drop iscroll 関数なし。
このすべてのソリューションの大きな問題は、入力の要素をスクロールすると、ページにスクロールがないことです。1 つまたは 2 つの入力を行う場合は問題ではありませんが、ページがフォームの場合、ページをスクロールするのに大きな問題があります。
私が提供する解決策は、入力をラベルタグでラップするか、入力へのポインター用にラベルタグを作成することです。次に、入力の上にラベルを絶対配置し、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% で動作しています。確認してください。
私はゲームに少し遅れていますが、誰かがまだ興味を持っている場合は、@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 の場合は、このソリューションを試してください') {
リターン; }