为什么我的JQuery插件在Firefox中完美运行但在IE中却不能?

时间:2010-11-09 14:46:02

标签: jquery-ui jquery-plugins internet-explorer-7

我正在使用JQuery 1.4.2,并尝试构建一个基本上显示表中选择列表的插件。我正在使用Jquery UI css类来格式化选择列表中出现的容器,并使用DataTables插件来格式化表,检索数据并过滤表。选择列表在FireFox 3.6中完美运行,但在IE 7中,列表永远不会出现。我不确定这是否是由于定位 - 我似乎无法弄清楚问题是什么。

(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%}

提前感谢任何/所有回复!


好的,所以选择列表表没有出现在页面上,因为不知何故div的top属性被设置为负值。

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

即使我单步执行代码,我也会通过偏移对象明确地将顶部和左侧设置为:

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

有人看到我在这里缺少什么吗?

2 个答案:

答案 0 :(得分:2)

我懒得设置这一切所以我可以从这里看到它,但如果我正在调试这个,我会使用IE F12工具找到我看不到的DOM的位,然后弄清楚为什么我看不到它们。

我也这么认为:

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

可能无效 - 您不能拥有空div,并且应该有<div blah-blah></div>

一般来说,我看到的很多浏览器差异在我正在做的事情上都是无效的,哪一个浏览器比另一个浏览器更容忍。

e.g。 Firefox将解析IE和Chrome不会使用的某些无效JSON。

答案 1 :(得分:0)

解决方案是将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();
}