Javascript在jsfiddle中工作,但在ASP .net中不起作用

时间:2013-04-16 17:09:52

标签: javascript asp.net .net

我想通过单击列表项中的一列/字符串来过滤项目列表。单击“销售”时,仅显示“销售”类别中的列表中的项目。当我再次点击销售时,将显示列表中的所有项目。

它在我jsfiddle

上的工作方式

但为什么它不能在ASP .net上的Visual Studio中工作?它在

中抛出异常
...
var a = p.getElementsByTagName("a")[0];
...

这是我的HTML代码:

<div data-role="page" id="page1">
    <div data-role="content">
        <ul data-role="listview" data-inset="false" data-filter="true" id="testList">
            <li data-icon="false">
                <p class="ui-li-heading"> 
                  <strong> 1</strong>
                </p>

                <p class="ui-li-aside"> 
                    <span>
                        <a href="javascript:void(0)" class="areaItem" id="areaItem">Sales</a>
                        &nbsp;
                        &nbsp;
                    </span>
 <span class="ui-icon ui-icon-gear" style="display: inline-block;"></span>
 <span class="ui-icon ui-icon-check" style="display: inline-block;"></span>    
                </p>
            </li>
  </div>
</div>

这是我的Javascript:

var filtered = 0;

$(".areaItem").click(function () {
    var SearchTerm = $(this).text();

    var ul = document.getElementById("testList");
    var liArray = ul.getElementsByTagName("li");

    for(var i=0; i<liArray.length; i++) {
        var p = liArray[i].getElementsByTagName("p")[0];
        var a = p.getElementsByTagName("a")[0];

        if(filtered == 1) {
            $(liArray[i]).show();
        } else {
            if(a.text.localeCompare(SearchTerm) != 0) {
                $(liArray[i]).hide();
            }
        }
    }

    if (filtered == 0) {
        filtered = 1;
    } else {
        filtered = 0;
    }
});

3 个答案:

答案 0 :(得分:2)

我将从重构你的javascript开始:

$(document).ready(function () { //Make sure doc is loaded
   var list = $("#testList");
   var listItems = $(list).find("li"); //could also do $("#listtest li);

   $(".areaItem").click(function () {
       var parentLi = $(this).closest("li");   //Get li that encloses clicked item 
       $(listItems).not(parentLi).toggle();    //Toggle display of other li
   });
});

它更简单,更符合jQuery的使用方式。

请参阅:http://jsfiddle.net/5pMsR/3/

这本身就不足以解决你的问题。仔细检查呈现给页面的内容。特别要检查id,因为ASP.net因修改ID而臭名昭着。谷歌ASP.net名称mangling和asp.net ID mangling获取更多信息。如果您的ID被破坏,请在脚本中使用以下内容

var list = $('#<%= YourListElement.ClientID%>');

或使用课程。

<强>更新

重新阅读您的问题后,我意识到我的解决方案可能无法满足您的需求。如果您希望同时显示其中任何一个“销售”项目,则可以使用以下内容:

var list = $("#testList");
var listItems = $(list).find("li"); //could also do $("#listtest li);

$(".areaItem").click(function () {
    var parentLi = $(this).closest("li");  //Get Parent li of clicked element
    var filter = $(parentLi).find(".areaItem").text(); //Set Filter based on text of clicked item
    $(listItems).filter(function(){ //Use jQuery filter to find based on text
        //in the filter context 'this' is a li being filtered not the item clicked
        //$(this).find(".areaItem").text() is used to compare against all list items text
        return $(this).find(".areaItem").text() != filter;
    }).toggle();

});

请参阅:http://jsfiddle.net/5pMsR/8/

更新2

我已经更新了代码并按上述方法进行操作,以便根据评论使解决方案更加健壮。似乎最终渲染中不存在a标记。现在,代码更改将基于CSS类而不是标记进行搜索。

答案 1 :(得分:1)

我过去遇到过类似的问题:问题出在ASP.NET页面生命周期和在DOM中创建元素之前解析的javascript。由于您尝试将单击处理程序绑定到.areaItem类,因此在解析函数时,该类成员的元素必须在DOM中都可用。

从记忆中我觉得我最终将点击委托给了文件:

$(document).on(click, ".areaItem", function() { <function content> });

我相信这会使解析发生在load事件之后,此时所有元素都已创建。

我不确定的原因是因为我删除了所有这些代码并以不同的方式执行:在ASP控件和HTML之后将脚本块直接放在我的内容页面中。如果您想在标题或单独的文件中使用JS,但在内容看起来有效后嵌入它,则不理想:

<div data-role="page" id="page1">
<div data-role="content">
    <ul data-role="listview" data-inset="false" data-filter="true" id="testList">
        <li data-icon="false">
            <p class="ui-li-heading"> 
              <strong> 1</strong>
            </p>

            <p class="ui-li-aside"> 
                <span>
                    <a href="javascript:void(0)" class="areaItem" id="areaItem">Sales</a>
                    &nbsp;
                    &nbsp;
                </span>
                <span class="ui-icon ui-icon-gear" style="display: inline-block;"></span>
                <span class="ui-icon ui-icon-check" style="display: inline-block;"></span>    
            </p>
        </li>
  </div>
</div>

<script>
  var filtered = 0;

  $(".areaItem").click(function () {
    var SearchTerm = $(this).text();

    var ul = document.getElementById("testList");
    var liArray = ul.getElementsByTagName("li");

    for(var i=0; i<liArray.length; i++) {
        var p = liArray[i].getElementsByTagName("p")[0];
        var a = p.getElementsByTagName("a")[0];

        if(filtered == 1) {
            $(liArray[i]).show();
        } else {
            if(a.text.localeCompare(SearchTerm) != 0) {
                $(liArray[i]).hide();
            }
        }
    }

    if (filtered == 0) {
        filtered = 1;
    } else {
        filtered = 0;
    }
});
</script>

答案 2 :(得分:0)

我带来的解决方案对我来说有点奇迹,因为我是javascript的新手。 一切都在IE中运行良好,但在Chrome中,所有li都会在点击后消失。

var filtered = 0;

        $(".areaItem").click(function () {
            var SearchTerm = $(this).text();

            $('#testList > li').each(function () {
                var a = $(this).find("a").attr("id","areaItem");

                //alert(a[0].innerHTML);

                if (filtered == 1) {
                    $(this).show();
                } else {
                    //alert(a.text());
                    if (a[0].innerHTML.localeCompare(SearchTerm) != 0) {
                        $(this).hide();
                    }
                }

            });


            if (filtered == 0) {
                filtered = 1;
            } else {
                filtered = 0;
            }
        });