为什么我的 jQuery-UI 对话框在包含所有脚本引用的情况下仍不起作用?

Why doesn't my jQuery-UI dialog work even though all script references are included?

我有一个 jQuery-UI,它应该作为 table 列 header 的过滤器。当我将实现编写为单独的 html 文件时,它工作得非常好。

这是一个包含所有脚本标签的文件。这里ColumnFilters.js下面是整个过滤框的实现,是一个对话框

    <!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />



    <script src="Scripts/jquery-1.10.2.js"></script>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/jquery-ui.js"></script>
    <script src="Scripts/jquery-ui.min.js"></script>
    <script src="Scripts/bootstrap.js"></script>
    <script src="Scripts/bootstrap.min.js"></script>
    <link href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" rel="stylesheet" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">


</head>
<body>
    <style>
        span i.glyphicon.glyphicon-filter {
            visibility: hidden;
        }

        span:hover i.glyphicon.glyphicon-filter {
            visibility: visible !important;
        }
    </style>
    <script src="ColumnFilters.js"></script>
    <form id="dialog" style="background-color:gainsboro" class="table-bordered">
        <select id="filterclause">
            <option selected>Equals</option>
            <option>Contains</option>
            <option>Does not Contain</option>
            <option>Not Equal to</option>
        </select>
        <div>
            <label for="FirstBox">Field 1</label>
            <input id="FirstBox" />
        </div>

                <!--<button type="submit" class="btn btn-primary">Submit</button>-->

        <div>
           <button class="btn btn-primary" id="ApplyFilter">Apply Filter</button>
            <button class="btn btn-primary" id="ClearFilter">Clear Filter</button>
        </div>
    </form>
     <div class="container">
        <h2>Basic Table</h2>
        <p>The .table class adds basic styling (light padding and only horizontal dividers) to a table:</p>
        <table class="table table-bordered" id="AddressTable">
            <thead>
                <tr>
                    <th data-filterclause="" data-filtervalue=""><span>Firstname</span>
                        <span style="float:right"><i class="glyphicon glyphicon-filter"></i></span>
                    <!--<span><i class="material-icons">filter_list</i></span>-->
                    </th>
                    <th data-filterclause="" data-filtervalue=""><span>Lastname</span>
                        <span style="float:right"><i class="glyphicon glyphicon-filter"></i></span>
                    </th>
                    <th data-filterclause="" data-filtervalue="">
                        <span>Email</span>
                        <span style="float:right"><i class="glyphicon glyphicon-filter"></i></span>
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>John</td>
                    <td>Doe</td>
                    <td>john@example.com</td>
                </tr>
                <tr>
                    <td>Mary</td>
                    <td>Moe</td>
                    <td>mary@example.com</td>
                </tr>
                <tr>
                    <td>July</td>
                    <td>Dooley</td>
                    <td>july@example.com</td>
                </tr>
            </tbody>
        </table>
    </div>

</body>
</html>

但是当我尝试在通过 MVC 框架创建的 table 中集成相同的实现时,它不起作用。以下是 MVC 页面的页面源 -

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shared - My ASP.NET Application</title>
    <link href="/Content/bootstrap.css" rel="stylesheet"/>
<link href="/Content/site.css" rel="stylesheet"/>
<link href="/Content/wait.css" rel="stylesheet"/>

    <script src="/Scripts/modernizr-2.6.2.js"></script>

    <script src="/Scripts/jquery-1.10.2.js"></script>
<script src="/Scripts/jquery-1.10.2.min.js"></script>
<script src="/Scripts/jquery-ui.js"></script>
<script src="/Scripts/jquery-ui.min.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/bootstrap.min.js"></script>

     <script src="/Scripts/jquery.unobtrusive-ajax.js"></script>




</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/">Application name</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a href="/">Home</a></li>
                    <li><a href="/Home/About">About</a></li>
                    <li><a href="/Home/Contact">Contact</a></li>
                    <li><a href="/Products">Products</a>/li>
                    <li><a href="/Customers">Customers</a>/li>
                    <li><a href="/Addresses/Shared">Addresses</a>/li>
                    <li><a href="/ProductModels">ProductModels</a>/li>
</ul>
            </div>
        </div>
    </div>

    <div class="container body-content">




<script>
    var filterindex = 0;
        $(document).ready(function ()
        {
            $("#dialog").dialog({
                autoOpen: false,
                closeOnEscape: true,
                draggable: true,
                title: "Filter Box"
            });
            $(".glyphicon .glyphicon-filter").click(function (e) {
                filterindex = $(event.target).closest('th').index();

                $("#dialog #filterclause").val($("th:eq(" + filterindex + ")").data("filterclause"));
                $("#dialog #FirstBox").val($("th:eq(" + filterindex + ")").data("filtervalue"));
                $("#dialog").dialog({

                    position: { at: "right bottom", my: "left top", of: $(e.target) }
                });
                $("#dialog").dialog("open");
            });
            $("#close").click(function () {

                $("#dialog").dialog("close");
            });

            $("#ApplyFilter").click(function (e) {

                e.preventDefault();

                $("th:eq(" + filterindex + ")").data("filterclause", $("#filterclause").find("option:selected").text());
                $("th:eq(" + filterindex + ")").data("filtervalue", $("#FirstBox").val());
                FilterAddressTable();
            });


            function FilterAddressTable() {

                $("#AddressTable tr").each(function () {

                    $(this).show();
                });

                $("#AddressTable th").each(function () {

                    var headerindex = $(this).index();


                    $(this).closest("table").find("tr:has(td):visible").each(function () {

                        if (!$("th:eq(" + headerindex + ")").data("filtervalue")) {
                            $("th:eq(" + headerindex + ")").find("span:has(i.glyphicon.glyphicon-filter)").find("i.glyphicon.glyphicon-filter").css("visibility", "hidden");
                        }
                        else {

                            $("th:eq(" + headerindex + ")").find("span:has(i.glyphicon.glyphicon-filter)").find("i.glyphicon.glyphicon-filter").css("visibility", "visible");

                            switch ($("th:eq(" + headerindex + ")").data("filterclause")) {

                                case "Equals":

                                    if ($(this).find("td:eq(" + headerindex + ")").text() === $("th:eq(" + headerindex + ")").data("filtervalue")) {
                                        $(this).show();
                                    }
                                    else {
                                        $(this).hide();
                                    }
                                    break;
                                case "Contains":

                                    if ($(this).find("td:eq(" + headerindex + ")").is(":contains(" + $("th:eq(" + headerindex + ")").data("filtervalue") + ")")) {
                                        $(this).show();
                                    }
                                    else {
                                        $(this).hide();
                                    } break;
                                case "Does not Contain":

                                    if ($(this).find("td:eq(" + headerindex + ")").is(":not(:contains(" + $("th:eq(" + headerindex + ")").data("filtervalue") + "))")) {
                                        $(this).show();
                                    }
                                    else {
                                        $(this).hide();
                                    } break;
                                case "Not Equal to": if ($(this).find("td:eq(" + headerindex + ")").text() != $("th:eq(" + headerindex + ")").data("filtervalue")) {
                                    $(this).show();
                                }
                                else {
                                    $(this).hide();
                                }
                                    break;
                            }
                        }
                    });
                });
            }

            $("#ClearFilter").click(function (e) {

                e.preventDefault();

                $("th:eq(" + filterindex + ")").data("filterclause", "");
                $("th:eq(" + filterindex + ")").data("filtervalue", "");
                FilterAddressTable();
            });

            var Options =
                {
                    url: "/Addresses/" + "Index",
                    type: "GET"
                };
            $.ajax(Options).done(function(data)
            {

                $("#DynamicView").html(data);

            });
            $(document).ajaxStart(function () {
                $("#ProductsTable").css('visibility', 'hidden');
                $(".signal").css('visibility', 'visible');
            });
            $(document).ajaxComplete(function () {
                $("#ProductsTable").css('visibility', 'visible');
                $(".signal").css('visibility', 'hidden');
            });



        });
    </script>

<link href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<style>
    span i.glyphicon.glyphicon-filter {
        visibility: hidden;
    }
     span:hover i.glyphicon.glyphicon-filter {
        visibility: visible !important;
    }
</style>
<div class="signal"></div>
<form id="dialog" style="background-color:gainsboro" class="table-bordered">
    <select id="filterclause">
        <option selected>Equals</option>
        <option>Contains</option>
        <option>Does not Contain</option>
        <option>Not Equal to</option>
    </select>
    <div>
        <label for="FirstBox">Field 1</label>
        <input id="FirstBox" />
    </div>

    <!--<button type="submit" class="btn btn-primary">Submit</button>-->

    <div>
        <button class="btn btn-primary" id="ApplyFilter">Apply Filter</button>
        <button class="btn btn-primary" id="ClearFilter">Clear Filter</button>
    </div>
</form>
<div id="DynamicView">
</div>




        <hr />
        <footer>
            <p>&copy; 2019 - My ASP.NET Application</p>
        </footer>
    </div>



<!-- Visual Studio Browser Link -->
<script type="application/json" id="__browserLink_initializationData">
    {"appName":"Chrome","requestId":"d5fb4162ac90439bb233266c5228c43c"}
</script>
<script type="text/javascript" src="http://localhost:3085/335000e36b2e4c7aa1efbc045945ee81/browserLink" async="async"></script>
<!-- End Browser Link -->

</body>
</html>

在此页面中,table 不可见,因为我正在从另一个 html 加载 table body。但是,标有 id=dialog 的部分应该作为对话框工作,并且当我单击 table header 上的图标时应该打开 - 这就是我在点击事件中配置它的方式过滤器图标。它没有打开,我已经尝试了所有方法,从将 ColumnFilters.js 代码放在 body 中到将所有脚本引用放在 body 中,这些 none 似乎都有效。

这里有一件事要看:

$(".glyphicon .glyphicon-filter").click(function(e) {
  filterindex = $(event.target).closest('th').index();
  $("#dialog #filterclause").val($("th:eq(" + filterindex + ")").data("filterclause"));
  $("#dialog #FirstBox").val($("th:eq(" + filterindex + ")").data("filtervalue"));
  $("#dialog").dialog({
    position: {
      at: "right bottom",
      my: "left top",
      of: $(e.target)
    }
  });
  $("#dialog").dialog("open");
});

正在传递 click 回调 e 但您调用的 event.target 不存在。这应该会导致如下错误:

Uncaught TypeError: Cannot read property 'type' of undefined
    at e.setFieldValue
    at HTMLFormElement.formKeydownListener

首先需要解决这个问题,以确保这不会妨碍该功能。

其次,$(".glyphicon .glyphicon-filter") 项似乎不存在。我没有看到包含 .glyphicon-filter.glyphicon 元素作为子元素。我确实看到 $(".glyphicon.glyphicon-filter"),这似乎工作正常。

这是我的测试代码:https://jsfiddle.net/Twisty/oLh5wf2z/9/

JavaScript

var filterindex = 0;
$(function() {
  $("#dialog").dialog({
    autoOpen: false,
    closeOnEscape: true,
    draggable: true,
    title: "Filter Box"
  });
  $(".glyphicon.glyphicon-filter").click(function(e) {
    filterindex = $(e.target).closest('th').index();

    $("#dialog #filterclause").val($("th:eq(" + filterindex + ")").data("filterclause"));
    $("#dialog #FirstBox").val($("th:eq(" + filterindex + ")").data("filtervalue"));
    $("#dialog").dialog({

      position: {
        at: "right bottom",
        my: "left top",
        of: $(e.target)
      }
    });
    $("#dialog").dialog("open");
  });
  $("#close").click(function() {

    $("#dialog").dialog("close");
  });

  $("#ApplyFilter").click(function(e) {

    e.preventDefault();

    $("th:eq(" + filterindex + ")").data("filterclause", $("#filterclause").find("option:selected").text());
    $("th:eq(" + filterindex + ")").data("filtervalue", $("#FirstBox").val());
    FilterAddressTable();
  });


  function FilterAddressTable() {

    $("#AddressTable tr").each(function() {

      $(this).show();
    });

    $("#AddressTable th").each(function() {

      var headerindex = $(this).index();


      $(this).closest("table").find("tr:has(td):visible").each(function() {

        if (!$("th:eq(" + headerindex + ")").data("filtervalue")) {
          $("th:eq(" + headerindex + ")").find("span:has(i.glyphicon.glyphicon-filter)").find("i.glyphicon.glyphicon-filter").css("visibility", "hidden");
        } else {

          $("th:eq(" + headerindex + ")").find("span:has(i.glyphicon.glyphicon-filter)").find("i.glyphicon.glyphicon-filter").css("visibility", "visible");

          switch ($("th:eq(" + headerindex + ")").data("filterclause")) {

            case "Equals":

              if ($(this).find("td:eq(" + headerindex + ")").text() === $("th:eq(" + headerindex + ")").data("filtervalue")) {
                $(this).show();
              } else {
                $(this).hide();
              }
              break;
            case "Contains":

              if ($(this).find("td:eq(" + headerindex + ")").is(":contains(" + $("th:eq(" + headerindex + ")").data("filtervalue") + ")")) {
                $(this).show();
              } else {
                $(this).hide();
              }
              break;
            case "Does not Contain":

              if ($(this).find("td:eq(" + headerindex + ")").is(":not(:contains(" + $("th:eq(" + headerindex + ")").data("filtervalue") + "))")) {
                $(this).show();
              } else {
                $(this).hide();
              }
              break;
            case "Not Equal to":
              if ($(this).find("td:eq(" + headerindex + ")").text() != $("th:eq(" + headerindex + ")").data("filtervalue")) {
                $(this).show();
              } else {
                $(this).hide();
              }
              break;
          }
        }
      });
    });
  }

  $("#ClearFilter").click(function(e) {

    e.preventDefault();

    $("th:eq(" + filterindex + ")").data("filterclause", "");
    $("th:eq(" + filterindex + ")").data("filtervalue", "");
    FilterAddressTable();
  });

  var Options = {
    url: "/Addresses/" + "Index",
    type: "GET"
  };
  $.ajax(Options).done(function(data) {

    $("#DynamicView").html(data);

  });
  $(document).ajaxStart(function() {
    $("#ProductsTable").css('visibility', 'hidden');
    $(".signal").css('visibility', 'visible');
  });
  $(document).ajaxComplete(function() {
    $("#ProductsTable").css('visibility', 'visible');
    $(".signal").css('visibility', 'hidden');
  });
});

更新

请评论:https://www.w3schools.com/cssref/css_selectors.asp

jQuery 和 CSS 使用选择器来帮助识别对象。

.class1.class2 Selects all elements with both name1 and name2 set within it's class attribute

.class1 .class2 Selects all elements with name2 that is a descendant of an element with name1 Hope that helps.

element>element Selects all

elements where the parent is a element

希望对您有所帮助。