【问题标题】:How can I add a jQuery UI icon to a dynamically generated button?如何将 jQuery UI 图标添加到动态生成的按钮?
【发布时间】:2012-10-19 14:29:24
【问题描述】:

下载 jQuery UI 时,您将获得一个样式表,用于选择任何主题,以及几个包含图标的图像文件。我已经想出了如何将图标添加到单个 <button> 元素,但是我有一种情况,我在网格 (jqGrid) 中动态生成按钮并想要使用这些图标。所以,假设我想使用 CSS 文件中的这个图标:

.ui-icon-trash { background-position: -176px -96px; }

然后,我通过处理gridComplete 事件将按钮添加到网格中:

gridComplete: function () {
    var ids = $("#myGrid").jqGrid('getDataIDs');
    for (var i = 0; i < ids.length; i++) {
        var deleteButton = "<button type='button' style='height: 22px;width: 20px;' title='Delete' onclick=deleteRow(" + ids[i] + ")></button>";
        $("#myGrid").jqGrid('setRowData', ids[i], { DeleteButton: deleteButton });
    }
}

我试过在按钮标签中使用一个类,例如deleteRowButton,然后像这样使用jQuery:

$(".deleteRowButton").button({
    icons: {
        primary: 'ui-icon-trash'
    },
    text: false
});

但这不起作用。我必须做些什么才能让我的按钮有这个图标?

【问题讨论】:

    标签: jquery jquery-ui jqgrid icons


    【解决方案1】:

    我想你的代码 $(".deleteRowButton").button({icons: {primary: 'ui-icon-trash'}, text: false}); 没有工作,因为你把它放在了错误的地方。如果您在gridComplete 内部创建&lt;button class='deleteRowButton' ...&gt;,您应该在您发布的代码之后直接调用$(".deleteRowButton").button(...)inside of gridComplete

    gridComplete: function () {
        var $this = $(this), ids = $this.jqGrid('getDataIDs'), l = ids.length,
            i, deleteButton;
        for (i = 0; i < l; i++) {
            deleteButton = "<button type='button' style='height:22px;width:20px;'" +
                " class='deleteRowButton' title='Delete' onclick=deleteRow(" +
                ids[i] + ")></button>";
            $this.jqGrid('setRowData', ids[i], { DeleteButton: deleteButton });
        }
        $(".deleteRowButton").button({
            icons: {
                primary: 'ui-icon-trash'
            },
            text: false
        });
    }
    

    the first demo

    上述方法的性能存在小问题。使用setRowData 在页面上进行更改。页面上的每次更改都会重新计算页面上存在的所有其他元素的位置。因此,为了提高性能,建议减少网格上的更改次数。所以更好的方法是使用custom formattrer。新版本的代码实际上将与前一个版本一样简单。您只需将formatter 定义为函数:

    { name: 'DeleteButton', width: 20,
        formatter: function (cellvalue, options) {
            return "<button type='button' class='deleteRowButton' " +
                "style='height: 22px;width: 20px;' title='Delete'></button>";
        }},
    

    并将gridCompleteloadComplete的代码缩减为

    gridComplete: function () {
        $(".deleteRowButton").button({
            icons: {
                primary: 'ui-icon-trash'
            },
            text: false
        }).click(function (e) {
            var $tr = $(e.target).closest("tr.jqgrow");
            alert("the row with id=" + $tr.attr("id") + " need be deleted");
        });
    }
    

    在您的原始代码中,方法deleteRow 必须是全局(它应该在顶层定义)。新代码只能使用click 事件处理程序。见the next demo

    顺便说一句,您实际上并不需要将每个 &lt;button&gt; 绑定到 click 事件处理程序。众所周知,如果按钮上没有click 事件处理程序,则会发生event bubbling。因此,不必每次在加载和重新加载网格时绑定click 事件处理程序,只需在整个网格体上定义一次相应的事件处理程序。换句话说,您可以使用onCellSelect 回调。使用起来很舒服,因为rowid 和单击单元格的列的索引已经计算过了。此外,根据onCellSelect 回调的第4 个参数e,您可以访问事件处理程序,其中e.tagret 是单击的&lt;button&gt; 的DOM 元素。所以可以将上面gridComplete的代码替换成如下代码:

    onCellSelect: function (rowid, iCol, cellcontent, e) {
        if ($(e.target).closest("button.deleteRowButton").length > 0) {
            alert("the row with id=" + rowid + " need be deleted");
        }
    },
    gridComplete: function () {
        $(".deleteRowButton").button({
            icons: {
                primary: 'ui-icon-trash'
            },
            text: false
        });
    }
    

    这样可以进一步提高性能并减少页面使用的内存。 The demo 实时显示最后的代码。在大多数情况下,您不需要使用像 $(e.target).closest("button.deleteRowButton").length &gt; 0 这样的结构。取而代之的是,您只需验证列索引iCol。如果需要,您可以改为测试列名。你可以使用

    $(this).jqGrid("getGridParam", "colModel")[iCol].name
    

    iCol 转换为对应的列名。

    【讨论】:

      【解决方案2】:

      我建议从 'button' 切换到 'input type="button"' 您应该能够使用 CSS 中的背景图像来设置图标。您的网格完成功能看起来像这样:

      gridComplete: function () {    
      var ids = $("#myGrid").jqGrid('getDataIDs');    
      for (var i = 0; i < ids.length; i++) {    
          var deleteButton = "<input type='button' class='HasIcon' style='height: 22px;width: 20px;' title='Delete' onclick=deleteRow(" + ids[i] + ")/>";    
          $("#myGrid").jqGrid('setRowData', ids[i], { DeleteButton: deleteButton });    
      }    
      

      }

      你的 CSS 看起来像这样:

      #myGrid input[type=button].HasIcon
      {
          background-image: url(/* icon location */);
          background-repeat: no-repeat;
          text-align: center;
          padding-left: 20px; /* slightly longer than your icon */
      }
      

      您不需要使用 jquery 来应用图标,因为 CSS 会为您做到这一点。 CSS 的魔力再次大获全胜! :-)

      【讨论】:

      • 谢谢弗兰基。由于图标实际上是包含所有图标的较大图像的一部分,我将为我的background-image URL 指定什么?这是图标集的链接:jquery-ui.googlecode.com/svn/tags/1.6rc5/tests/static/…
      • 嗯,这可能有点棘手。您需要做的是像这样指定背景偏移: background-position: -176px -96px;
      • 嗯,这不会缩小尺寸,因此您最终会显示所有其他图标。您可能可以使用名为“Before”的伪选择器,但我认为 IE8/7/6 不会支持它,但这意味着您必须选择按钮以外的其他东西,因为按钮不能包含其他元素(也许锚标签会很好)。见nicolasgallagher.com/css-background-image-hacks
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多