web-dev-qa-db-ja.com

<select>は、選択したオプションの最初の文字のみを表示します

オプションを追加してjqueryを使用して入力している標準の選択ボックスがありますが、何らかの理由でIE9には選択したオプションの最初の文字しか表示されません。言うまでもなく、FireFoxとChromeで完全に機能しますが、IE9をサポートする必要があります。 IE9互換モードを試しましたが、違いはなく、selectまたはoptionのスタイルも変わりませんでした。

誰かが以前にこの問題を見たことがあります。何が原因ですか?どのように修正しましたか?

Example of problem in IE9

簡略化されたコードサンプル:

<select id="selectCCY" ValueColumn="ccyID" DisplayColumn="ccySymbol" ></select>



$.each(res.result, function (key, value) {  
    $('#selectCCY').append('<option value="' + value[$('#selectCCY').attr('ValueColumn')]+ '">' + value[$('#selectCCY').attr('DisplayColumn')] + '</option>');
});

res.resultは、次のような単純なjson配列です。

[{"ccyID":1,"ccySymbol":"GBP"},{"ccyID":2,"ccySymbol":"AUD"},{"ccyID":3,"ccySymbol":"USD"}]

OH BUGGER !!!私の単純化した例ではうまく機能するので、問題はどこかにあります。ごめんなさい。元のコードはここに貼り付けるには長くて複雑ですが、答えが見つかったらお知らせします。

今度いつか....

OK、問題は$(selector).each()ループ内のajax呼び出しにありました。ループはすべての選択ボックスを通過し、オプションに非同期で入力されます。同期呼び出しを行うと、選択ボックスの幅が正しく表示されますが、非同期呼び出しの場合、選択ボックスには画像のように最初の文字のみが表示されます。まだこれに取り組んでいます、再びあなたに戻ります。

選択ボックスが正しく表示されない原因を知りたいのですが。回避策を実行して正しく表示することはできますが、それでは質問に答えられません。それはオプションを含む単なる選択です、それは常にうまくいくはずですよね?

問題を無視した週末の後..。

右私は回避策を見つけました。 ajax呼び出しを実行して選択ボックスにデータを入力する前に、まずcss displayプロパティを「none」に設定してから入力し、最後にajax呼び出しと入力が完了したら、cssdisplayの「none」プロパティを削除します。

だから私はまだIEが私を好きではない理由はわかりませんが、少なくとも解決策はあります。

46
Daniel Brink

これはIEのみの問題です。最初に選択ボックスのcss表示プロパティを「none」に設定し、次にajax呼び出しを介してデータを入力し、最後にajax呼び出しが完了して選択ボックスに入力します。が入力されている場合、選択ボックスのcss display'none 'プロパティを削除します

17
Daniel Brink

私の場合、ajaxリクエストが発生する前にselectを非表示にするイベントフックがなかったため、事後にselect要素を強制的に再描画する必要がありました。既存の幅を再適用することはうまくいくようです:

$("select").width($("select").width());
24
Jim Thomas

ジムの答えに基づいて、ドロップダウンリストをこのメソッドに渡します。

// force redraw to get around bug in IE.
// NOTE that this removes width from the style attribute.
function forceRedraw(jqueryObject) {
    jqueryObject.css('width', 0);
    jqueryObject.css('width', '');  // remove from style tag
}

これはIEのバグを回避し、メソッドが呼び出される前の要素の幅を残します限り幅はスタイル属性ではなくCSSで指定されます。

11
apollodude217

私はangularjsを使用しており、ie8/ie9でもこの問題が発生しています。このアプローチ/回避策は私にとってはうまくいきました:例:このように見えるhtmlで:

<select ng-show="data.showSelect" ng-cloak ng-model="data.model" ng-options="l.id as l.name for l in data.items></select>

ドロップダウンのデータが読み込まれた後にこのコードを実行すると、問題が修正されます

$timeout(function(){$scope.data.showSelect = true;},100);

この回避策が必要なサイトに複数の領域がある場合は、これをディレクティブにラップすることもできると思います。

3
mjj1409

私の場合はコールバックがあったので、入力中に表示をnoneに設定することはできませんでしたが、@ Daniel Brinksの回答を詳しく説明して問題を解決することができました。アイテムが追加され、表示が「なし」から「なし」に変更され、今後追加されるすべてのアイテムが正常になります。jqueryとウィジェットを使用します。したがって、ウィジェットを修正してIEあなたに便利です。

ウィジェットの_create関数内:

this.availableFields = $("<select multiple='multiple' name='AvailableFields'></select>")
                                .addClass("ui-fieldselector-available-select")
                                .css("display", "none")
                                .appendTo( this.element );

ウィジェットの_init関数内:

buildAvailableItem-選択に追加します

次に、ウィジェットの状態を追跡する配列に追加します

var $this = this;
                //IE HACK Part 1--
                $this.buildAvailableItem("Loading...", "Loading..." );
                $this.availableList.Push("Loading...");
                //----------------
    //do stuff, here I initialize some functionality, like drag and drop, add click events, etc.
                //IE HACK Part 2--
                $($this.availableFields).css("display", "");
                $this.removeAvailableOption("Loading...");
                //----------------
    // AJAX adding

私は通常、アイテムの作成とリストへの追加を処理するaddAvailableItemという関数を使用しますが、これもイベントをトリガーするため、「Loading ...」アイテムに対してイベントをトリガーしたくありませんでした。

何らかの理由で誰かが非常に遅いブラウザを使用している場合、それが削除されてajaxアイテムが追加される前に、「読み込み中...」と表示されます。

コピーアンドペーストに適したバージョンが必要な場合は、お知らせください

参考までに、ビルドアイテムは次のとおりです。

buildAvailableItem: function (display, value)
        {
            $("<option>" + display + "</option>").val(value).appendTo(this.availableFields);
        },
1

Angle.jsのselectDirectiveのレンダリング関数の次の場所(太字で**としてマークされている)に数行を追加すると、問題なく機能しました。以下に示すangularJSまたはforEachにパッチを適用する以外に可能な解決策があるかどうかを探していますか?

if (existingOption.label !== option.label) {
  lastElement.text(existingOption.label = option.label);
  **lastElement.attr('label', existingOption.label);**
}

そして

  (element = optionTemplate.clone())
      .val(option.id)
      .attr('selected', option.selected)
      .text(option.label);
  **element.attr('label', option.label);**

問題は、IEでラベルが空白の場合、HTMLOptionElementのラベル属性がテキスト属性と同じではないことでした。

これは、画面が読み込まれた後に次のコードを追加し、FFのWebコンソールとIEを見て違いを確認することで確認できます。ラベルが設定されている最後の行のコメントを解除すると、テキストに変換すると正常に機能します。または、上記のようにangular.jsにパッチを適用します。

// This is an IE fix for not updating the section of dropdowns which has ng-options with filters
angular.forEach($("select"), function (currSelect) {
    console.log("1.text ", currSelect.options[currSelect.selectedIndex].text);
    console.log("1.label ", currSelect.options[currSelect.selectedIndex].label);
    //console.log("1.innerHTML ", currSelect.options[currSelect.selectedIndex].innerHTML);
    //console.log("1.textContent ", currSelect.options[currSelect.selectedIndex].textContent);
    //console.log("1.cN.data ", currSelect.options[currSelect.selectedIndex].childNodes[0].data);
    //console.log("1.cN.nodeValue ", currSelect.options[currSelect.selectedIndex].childNodes[0].nodeValue);
    //console.log("1.cN.textContent ", currSelect.options[currSelect.selectedIndex].childNodes[0].textContent);
    //console.log("1.cN.wholeText ", currSelect.options[currSelect.selectedIndex].childNodes[0].wholeText);
    //console.log("1. ", currSelect.options[currSelect.selectedIndex], "\n");

    //currSelect.options[currSelect.selectedIndex].label = "xyz";
    //currSelect.options[currSelect.selectedIndex].label = currSelect.options[currSelect.selectedIndex].text;
});
1
A. S. Ranjan

Select要素の初期化方法(jQueryウィジェット内で動的に作成される)を変更することで、同じ問題を修正しました。

例A

これは機能しません:

var select = $('<select size=7>') // IE9 'first character' bug

これは行います:

var select = $('<select>').attr('size', 7) // Yay

例B

同様に、以下は機能しません。

self.element.append('<select name="mySelect">'); // IE9 'first character' bug

これは:

var mySelect = $('<select>').attr('name', 'mySelect');
self.element.append(mySelect);

結論

上記を説明できるようにしたいと思いますが、私は説明できないのではないかと思います。とにかく、これにより、CSSハックをコードに不必要に追加する手間を省くことができます。

0
Matt Carr