私はこの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では動作しません。 selectboxをタップしても何も起こりません。
問題を引き起こしている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()
イベント内にないため、このコードを必ず挿入する必要があります[〜#〜] after [〜#〜] the select
要素が定義されているHTML。
モバイルデバイスの場合、イベントは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(); },
入力、選択、テキストエリアタグに焦点を当てることができます
最後に、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);
}
});
このコードから始めます。この解決策は私にとってうまくいきました:
<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>
行の置き換え、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);
});
}
私は遅れましたが、私はあなたに私の解決策を残します。
JQueryを使用している場合は、それを試すことができます。
$('input, textarea, button, a, select').off('touchstart mousedown').on('touchstart mousedown', function(e) {
e.stopPropagation();
});
彼は誰でも。
私はあなたのすべての答えについて知っていますが、私は提供する新しい方法を持っています。 Javaスクリプトまたはドロップ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%で動作しています。確認してください
// 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
});
私にとっては、最後の行にクリック:trueを追加するだけです...一日中デバッグして、提案されたすべてのソリューションを実装して無駄にしています...
OnBeforeScrollStart()でフォーム要素を除外した場合でも、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
「-webkit-transform」CSSスタイルのdivの入力要素に漢字を入力することはできません。 iscroll 4はスクローラーdivで「-webkit-transform」を適用しました。
解決策は、フォームフィールドをスクローラーの絶対div内に保持することです。
Androidブラウザーのバグは、Android内の非常に古いバージョンのWebKitの結果であり、Android 4.3。 Android Chromeブラウザは内部でWebKitライブラリをアップグレードしたため、このバグから解放されます。
Android GoogleからのWebKitアップグレードを待機しています。
(e.target.nodeName.toLowerCase()== "select" || e.target.tagName.toLowerCase()== 'input' || e.target.tagName.toLowerCase()== 'textarea '){
戻る; }
ここに私のために働いた本当に簡単な修正があります。 Androidブラウザでは、最初のページの読み込み時に選択ボックスをクリックできなかったが、検索に使用しているテキスト入力フィールドをクリックできたことがわかりました。その後、テキスト入力フィールドをクリックした後、選択ボックスをクリックしたことが認識されるので、検索ページの読み込みに使用しているJavaScript関数にこれを追加するだけでした...
$('#search').focus();
そのため、検索ページが読み込まれると、テキスト入力フィールドに自動的にフォーカスしますが、キーボードはポップアップしません。これはまさに私が望んでいたことです。申し訳ありませんが、私の例は公開されていませんが、うまくいけば、これはまだ誰かを助けることができます。
これをチェックして。これで問題が解決しました
https://github.com/cubiq/iscroll/issues/576
オプションで選択しました
click:false, preventDefaultException:{tagName:/.*/}
私は少しゲームに遅れましたが、誰かがまだ興味がある場合は、@ 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);
}
}
基本的には、ユーザーがフォーム要素を選択したとき、実際にスクロールを開始する前(onBeforeScrollStart)、およびユーザーが要素内のカスタム属性data-iscroll="scroller"
をクリックすると、iScrollインスタンスを破棄するだけです。 、通常どおりiScrollを使用してスクロールできます。
<div data-role="page" id="pageNameHere" data-iscroll="enable">
Androidのバグがあり、-webkit-transform:translate3dが選択ボックスまたはパスワードボックス[1]のあるコンテナーに適用されている場合。これらの要素をアクティブにするボックス領域が移動し、さらに、パスワードボックスは別の場所にペイントするため、1つではなく2つの入力要素があるように見えます。
私はAppMobiで働いており、これらを修正したツールキットライブラリを開発しました。カスタムの選択ボックスウィジェットと、パスワード入力フィールドの置き換えを実装しました。以下をご覧ください。
https://github.com/imaffett/AppMobi.toolkit
[1]コメントの作成者がこのバグについて話していると思います https://bugs.webkit.org/show_bug.cgi?id=50552
それは私にとってうまくいきます!:
$('input, select').on('touchstart', function(e) {
e.stopPropagation();
});