4

IE7およびFF15.0.1では次のコードが期待どおりに機能するのに(選択に基づいてドロップダウンリストのサイズを変更する)、Chrome 23.0.1271.91では常にサイズ1になるのはなぜですか?

console.logを追加して実際に何が起こっているかを確認しようとしましたが、Chromeではサイズ変更機能が2回実行されているようですが、jQueryの初心者であるため、オブジェクトの受け渡しについてはまだよくわかりません。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=windows-1250">
  <title></title>

  <script type="text/javascript" src="jquery-1.8.3.min.js"></script>          
  <script type="text/javascript">                                         

   var vt = new Array('1','2','3','4','5');
   var x = 1;

   function addopts(ddl) {
       console.log(ddl);
       for ( var i = 0; i < vt.length; i++ ) {
           var v = i * x;
           $(ddl).append("<option value='" + v + "'>" + v + "</option>");
       }
       console.debug(ddl);

       vt.push(x);
       x++; // our list changes
   }

   function resize(ddl) {

       console.log(ddl);

       ddl.size = $(ddl).val();
       $(ddl).empty();  // in case our list needs to change completely
       console.log(ddl);

       addopts(ddl);
       console.log(ddl);
   }

    jQuery(document).ready(function() {   
        console.log(this);
        $('#group').change(function() {
            console.log(this);
            resize(this);
        });
    });

  </script>                                                               

  </head>
  <body>
    <form>
     <select id='group' size='1'>
      <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>
     </select>
    </form>
  </body>
</html>

↪JSFiddleでこのコードを表示する

どんな洞察もありがたいです。

4

1 に答える 1

2

これは確かに2つの点でChromeの問題のようです。多くのテストの結果、Chrome23と24の両方で次の問題が見つかりました。

  1. jQueryの.change&&.on("change"JavaScriptの.onchange関数は、実際にはchromeでのみ2回起動 します
    • これに対する答えはありません。以下に投稿する回避策を見つけました。
  2. Chromeには、選択ボックスのレンダリングに使用できる奇数のサイズがないようです。

    • Chromeは、選択ボックスを再レンダリングするために、最も近い偶数にサイズ変更されているように見えます(切り上げていることに気付いたと思います)。

    • 更新さらなるテストにより、(少なくともバージョン24では)偶数へのこのレンダリングは問題のみであり、サイズ0から4にのみ適用されることが示されています!

私が言及した回避策は、選択を新しいインスタンスに設定するためにタイマーを投入するのと同じくらい簡単であり、したがって、二重の発砲を無効にします。私の用語がsuxである場合は、許してください。ポイントは、変更時にChromeが1回だけ起動するのに役立ち、他のブラウザには影響しません(私が見つけた限り)

私はまた、単に私が読みやすくするために、あなたのコードを少し書き直す自由を取りました(あなたのコードは少し「拡張された」ように見えました)

jsFiddleの例

私が使用したスクリプト

var vt = new Array('1','2','3','4','5'),
    x = 1;

//  Since jQuery 1.1+ (i think) you no longer need the long written `$(document).ready`.
//  Now you can do the same thing with the short-hand below
$(function() {
    //  The selector you get. The .on() function is relativly new to jQuery and simply provides an easy way to bind events to elements
    //  You can also use .off to unbind a function to an element, for instance, i could wrap the inner function in a func named `reSize`
    //      and then add it and remove it with:
    //          - To add event: $("#group").on("change", reSize)
    //          - To remove event: $("#group").off("change", reSize)
    $("#group").on("change", function(e) {
        //  I create a variable of $(this) simply to pass it to the Timer function
        var $this = $(this);
        setTimeout(function() { //  basic JavaScript here
            //  Prop is also kind of new to jQuery. You used to just use `.attr()`, but now jQuery distinguishes between Attributes and Properties
            //  Since "size" is a Property of the select element, I use .prop to get/set the value
            //      In this case I'm of course setting the size to the current value
            //  One nice feature of jQuery you'll see here is "chaining"
            //      as you notice, i added the `.empty` to the end, since each jquery function generally returns the element object you started with
            //          Of course, had I only been GETting the value of size, this would not be the case
            $this.prop("size", $this.val()).empty();
            for (i=0;i<vt.length;i++) { //  basic JavaScript here
                var v = i*x;    //  your initial setup
                //  Here I replaced the append function you had with much more readable code.
                //  There are several ways to do this in jQuery, however
                //      fragmented Strings are not ever really suggested
                //  This could have also been written:
                //      $this.append($("<option />", { text: v, value: v }));
                $this.append($("<option />").val(v).text(v));
            }
            vt.push(x); //  more basic JavaScript
            x++;
            //      The following was used for debugging on the fiddle
            console.log(x)
            $("#selectSize").text($this.prop("size"));
        });
    });
})

いくつかの役立つ**jQuery**リンク

そして、あなたを助けるためだけに。再び独立した関数にしたい場合は、関数が分離されているため、どの選択にも適用できることを除いて、以下は上記とまったく同じです。

var vt = new Array('1','2','3','4','5'),
    x = 1;

function reSizeSelect(e) {
    var $this = $(this);
    setTimeout(function() {
        $this.prop("size", $this.val()).empty();
        for (i=0;i<vt.length;i++) {
            var v = i*x;
            $this.append($("<option />").val(v).text(v));
        }
        vt.push(x);
        x++;
        console.log(x)
        $("#selectSize").text($this.prop("size"));
    });
}

$(function() {
    $("#group").on("change", reSizeSelect);
})
于 2012-11-29T16:38:42.023 に答える