Почему мой плагин JQuery отлично работает в Firefox, а не в IE? - PullRequest
0 голосов
/ 09 ноября 2010

Я использую 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 получает отрицательное значение.

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

Несмотря на то, что когда я шагаю по коду, я явно устанавливаю верхнюю и левую сторону объекта смещения на:

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

Кто-нибудь видит, чего мне здесь не хватает?

Ответы [ 2 ]

2 голосов
/ 09 ноября 2010

Я слишком ленив, чтобы все это настроить, чтобы я мог видеть это отсюда, но если бы я отлаживал это, я использовал бы инструменты 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>

В целом, многие различия между браузерами, которые я вижу, оказываются недействительными в том, что я делаю, и к которому один браузер более терпим, чем другой.

например. Firefox проанализирует некоторые виды недействительных JSON, а IE и Chrome - нет.

0 голосов
/ 16 ноября 2010

Решение состояло в том, чтобы связать позицию 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();
}
...