代码之家  ›  专栏  ›  技术社区  ›  Griff

为什么我的JQuery插件在Firefox中工作得很好,但在IE中却没有?

  •  0
  • Griff  · 技术社区  · 14 年前

    我正在使用JQuery 1.4.2,并试图构建一个插件,它实际上显示了一个表中的选择列表。我正在使用Jquery UI css类格式化pick列表出现在其中的容器,并且 DataTables 用于格式化表、检索数据和筛选表的插件。选择列表在Firefox3.6中工作得很好,但在IE7中,这个列表从未出现过。我不确定这是否是定位造成的——我似乎不知道问题出在哪里。

    (function($) {
      // Shell for the plugin code
      $.fn.tablePicker = function(options) {
        // Plugin code
        var tbl = null;
        var options= options = $.extend({},$.fn.tablePicker.defaults, options); 
        return this.each(function() {
          // for each item in selector
          tbl= $('#'+options.tblName);
          $(tbl).wrap(options.container);
          if(options.header != null){
              var headerHtml= '<div align="center">' + options.header + '</div>';
              $(this).find("#tp-container").prepend(headerHtml);
          }
          $(this).addClass("ui-hidden-on-load").addClass("ui-tablepicker");
          $(this).addClass("ui-widget").addClass("ui-widget-content");
          $(this).addClass("ui-helper-clearfix").addClass("ui-corner-all");
          $(this).addClass("ui-helper-hidden-accessible");
          $(this).css("position", options.position);
          var offsetFromObject= null;
          var offset= {top:null, left:null};
          try {
              if(options.forinput){
                  offsetFromObject= options.forinput;
              }else if(options.forAnchor) {
                  offsetFromObject= options.forAnchor;
              }else{
                  alert("Warning: Tablepicker plugin did not find any control to bind to.");
              }
              // Use the specified parameter first
              if(options.top != null){
                  offset.top= options.top;
              }else{
                  var t= $("#"+offsetFromObject).offset();
                  offset.top= t.top;
              }
              if(options.left != null){
                  offset.left= options.left;
              }else{
                  var l= $("#"+offsetFromObject).offset();
                  offset.left= l.left;
              }
              $(this).offset(offset);
              $(this).css("z-index", "1");
          } catch (e) {
            alert('Tablepicker problem' + e);
          }
          tbl= _setUpDataTable(tbl);
          _performBindings(tbl, this);
    
    
        });
        function _setUpDataTable(tbl){
            tbl= $(tbl).dataTable( {
                "aoColumns"         : options.aoColumns,
                "bFilter"           : options.bFilter,
                "bPaginate"         : options.bPaginate,
                "bLengthChange"     : options.bLengthChange,
                "bAutoWidth"        : options.bAutoWidth,
                "sScrollY"          : options.sScrollY,
                "sPaginationType"   : options.sPaginationType,
                "bProcessing"       : options.bProcessing,
                "sAjaxSource"       : options.sAjaxSource
            });
            return tbl;
        };
        function _performBindings(dataTable, picker){
            var tableName= options.tblName;
            // Bind hide list to all inputs
            var tableFilter= tableName + '_filter';
            $('input, select').live('focus', function(event) {
                if ($(event.target).parent().attr('id') != tableFilter) {
                    _hideList(picker); // Don't hide the list on the datatable filter input focus.
                }
            });
            // Don't bind hide list to the field we want to show the list for
            if(options.forinput != null){
                var inputToBind=$('#'+options.forinput);
                $(inputToBind).unbind('focus');
                // Bind to the field to show the list on.   
                $(inputToBind).focus(function() {
                    if (!$(picker).is(':visible')) {
                        $(picker).slideToggle();
                    }
                });
            }
            // Allow binding to an anchor
            if(options.forAnchor != null){
                $("#"+options.forAnchor).click(function() {
                    if (!$(picker).is(':visible')) {
                        $(picker).slideToggle();
                    }
                });
            }
            // Bindings for mouse over on table
            var tbl= $('#'+tableName); 
            $(tbl).find('tbody tr').live('mouseover mouseout', function(event) {
                if (event.type == 'mouseover') {
                    $(this).addClass('hover');
                } else {
                    $(this).removeClass('hover');
                }
            });
            // handle the click event of the table
            $(tbl).find('tbody tr').live('click', function(event, ui) {
                var aData = dataTable.fnGetData(this);
                if (aData != null) {
                    $.isFunction(options.onClick) && options.onClick.call(this, aData);
                }
                _hideList(picker);
                dataTable.fnFilter(""); // clear the datatable filter on select.
                $("#"+tableFilter).find("input").val("");
    
            });
            // Hide list on esc.
            $(document).keyup(function(e) {
                if (e.keyCode == 27) { // esc
                        _hideList(picker);
                    }
            });
    
        }
        function _hideList(picker) {
            if ($(picker).is(':visible')) {
                $(picker).slideToggle();
            }
        }
    
      }
      $.fn.tablePicker.defaults = {
        header      :   null,
        container   :   '<div id="tp-container" class="ui-datepicker-header ui-widget-header ui-helper-clearfix ui-corner-all"/>',
        position    :   'absolute',
        top         :   null,
        left        :   null,
        tblName     :   'list_table',
        forinput    :   null,
        forAnchor   :   null,
        aoColumns   :   null,
        bFilter     :   true,
        bPaginate   :   true,
        bLengthChange : false,
        bAutoWidth  :   true,
        sScrollY    :   "200px",
        sPaginationType : "full_numbers",
        bProcessing :   true,
        sAjaxSource :   null,
        onClick     :   null
    
      };
    })(jQuery);
    

    $("#engine-picker").tablePicker(
           {forinput: "engineFamily",
              header: "Pick an Engine Family from this list. Use Search to narrow list.",
             onClick: function(data){
                var id = data[0];
                var family = data[1];
                var vendor = data[2];
                var year = data[3];
                var source = data[4];
                var usesOdometer= data[5];
                $("#engineId").val(id);
                $("#engineFamily").val(family);
                $("#engineMfg").val(vendor);
                $("#engineYear").val(year);
                $("#odometer").val(usesOdometer);
            },
            aoColumns: [ {"bVisible" : false}, null, null, null, null, {"bVisible" : false}],
            sAjaxSource: './enginelist-data.do',
            top: 296,
            left:602
    });
    

    CSS类:

    .ui-hidden-on-load{display: none;}
    .ui-tablepicker { width: 35em; padding: .25em .25em 0; z-index: 1}
    .ui-tablepicker .ui-tablepicker-header { position:relative; padding:.2em 0; }
    .ui-widget-header div{ width: 100%}
    

    提前感谢您的回复!


    Z-INDEX: 1; LEFT: 404px; POSITION: absolute; TOP: -736px 
    

    即使当我单步执行代码时,我还是通过offset对象显式地将top和left设置为:

    -   offset  {...}   Object
        top 296 Long
        left    602 Long
    

    有人看到我在这里丢失了什么吗?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Will Dean    14 年前

    我太懒了,无法设置所有这些,所以我可以从这里看到它,但如果我调试这个,我会使用IEF12工具来查找我看不到的DOM的位,然后找出我看不到它们的原因。

    我还认为:

    <div id="tp-container" class="ui-datepicker-header ui-widget-header ui-helper-clearfix ui-corner-all"/>
    

    <div blah-blah></div>

    总的来说,我看到的许多浏览器差异在我所做的事情中都是无效的,一个浏览器比另一个浏览器更能容忍。

    e、 Firefox会解析一些无效的JSON,而IE和Chrome不会。

        2
  •  0
  •   Griff    14 年前

    解决方案是将css位置链接到显示该表的JQuery命令堆栈。出于某种原因,这在FireFox中似乎不是问题,但在IE7中却是如此。

    (function($) {
      // Shell for the plugin code
      $.fn.tablePicker = function(options) {
        // Plugin code
        var tbl = null;
        var options= options = $.extend({},$.fn.tablePicker.defaults, options);
        var offset= {top:null, left:null};
    return this.each(function() {
    // for each item in selector
    tbl= $('#'+options.tblName);
    offset= $(this).offset(); ...
    

    然后我用传递插件引用的方法替换了显示列表的所有位置:

    function _showList(picker){
        var t= offset.top;
        var l= offset.left;
        $(picker).css("top", t+"px").css("left", l+"px").slideToggle();
    }