【问题标题】:Method fired multiple times on click event方法在点击事件上多次触发
【发布时间】:2017-09-22 16:53:03
【问题描述】:

我正在构建一个 Web 应用程序,用户可以在其中输入任何关键字或语句,并使用 wikipedia API 从 wikipedia 获得 20 个结果。 AJAX 工作得很好。当网络应用从维基百科拉取数据时,它应该在动态创建的 DIV 中显示每个结果。

发生的情况是,当点击事件被触发时,二十个 DIV 被创建了五次,总共一百个。我不知道为什么,但正如您在下面的 sn-p 中看到的那样,Web 应用程序为每个在触发 click 事件时(通过 .hide)隐藏的 DOM 元素创建了 20 个 DIV。

代码如下:

function main() {

function positive() {

    var bar = document.getElementById("sb").childNodes[1];
    var value = bar.value;
    if (!value) {
    	window.alert("Type in anything to start the research");
    } else {
    	var ex = /\s+/g;
    	var space_count = value.match(ex);
    	if (space_count == null) {
            var new_text = value;
    	} else {
    		new_text = value.replace(ex, "%20");
    		//console.log(new_text);
    	}

        url = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=&list=search&continue=-%7C%7C&srsearch=" + new_text + "&srlimit=20&sroffset=20&srprop=snippet&origin=*";

        var request = new XMLHttpRequest();
        request.open("GET", url);
        //request.setRequestHeader("Api-User-Agent", "Example/1.0");
        request.onload = function() {
	        var data = JSON.parse(request.responseText);
	        render(data);
	        //console.log(data);
        }
        request.send();
    }

}

function render(data) {

    $("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow", function() {
    	$("#sb input").css({
    		"float":"left",
    		"margin-left":"130px"
    	});
    	$("#first_btn").css({
    		"float":"left"
    	});
      
          var title = data.query.search[0].title;
          var new_text = document.createTextNode(title);
    	    var new_window = document.createElement("div");
          new_window.appendChild(new_text);
          new_window.setAttribute("class", "window");

    	    var position = document.getElementsByTagName("body")[0];
    	    position.appendChild(new_window);

      //}
    });
        
}

var first_btn = document.getElementById("first_btn");
first_btn.addEventListener("click", positive, false);

}

$(document).ready(main);
html {
	font-size: 16px;
}

* {
	margin: 0;
	padding: 0;
	box-sizing: border-box;ù
}

.align {
	text-align: center;
}

#first_h1 {
	margin-top: 30px;
}

#first_h3 {
	margin-bottom: 30px;
}

#sb {
	margin-bottom: 10px;
}

#second_h1 {
	margin-top: 30px;
}

#second_h3 {
	margin-bottom: 30px;
}

.window {
	width: 70%;
	height: 150px;
	border: 3px solid black;
	margin: 0 auto;
	margin-top: 20px;
}
<!DOCTYPE html>
<html lang="en">
<head>
	<title>Wikipedia Viewer</title>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>

	<h1 class="align" id="first_h1">Wikipedia Viewer</h1>
	<h3 class="align" id="first_h3">Type in a key word about the topic you are after<br>and see what Wkipedia has for you..</h3>

	<p class="align" id="sb">
		<input type="text" name="search_box" placeholder="Write here">
		<label for="search_box">Your search starts here...</label>
	</p>
	<p class="align" id="first_btn">
		<input type="submit" value="SEND">
	</p>

	<h1 class="align" id="second_h1">...Or...</h1>
	<h3 class="align" id="second_h3">If you just feel eager of random knowledge,<br>punch the button below and see what's next for you...</h3>

	<p class="align" id="second_btn">
		<input type="submit" value="Enjoy!">
	</p>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script>
	window.jQuery || document.write('<script src="js/jquery-3.2.1.min.js"><\/script>')
    </script>
	<script type="text/javascript" src="js/script.js"></script>
</body>
</html>

我通过删除 for 循环使代码更易于阅读。如您所见,即使只有一个结果,它也会显示五次。

你们知道为什么会这样吗? 谢谢

【问题讨论】:

    标签: javascript jquery ajax


    【解决方案1】:

    行:

    $("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow", function() {})
    

    说,对于这个“列表”中的每个元素,隐藏元素并在隐藏后运行这段代码。

    【讨论】:

      【解决方案2】:

      这段代码是罪魁祸首:

      $("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow", 
      function() {...});
      

      回调函数被调用五次,列出的每个 ID 调用一次,而不是像您预期的那样对所有 ID 调用一次。

      一种解决方法是创建一个类(例如,“hideme”),将其应用于您要隐藏的每个元素,然后编写:

      $('.hideme').hide("slow", function() {...});
      

      【讨论】:

        【解决方案3】:
        function render(data) {
        
            $("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow", function() {
                $("#sb input").css({
                    "float":"left",
                    "margin-left":"130px"
                });
                $("#first_btn").css({
                    "float":"left"
                });
            });  // Finish it here..
                  var title = data.query.search[0].title;
                  var new_text = document.createTextNode(title);
                    var new_window = document.createElement("div");
                  new_window.appendChild(new_text);
                  new_window.setAttribute("class", "window");
        
                    var position = document.getElementsByTagName("body")[0];
                    position.appendChild(new_window);
        
              //}
          //  });   Move this line..
        
        }
        

        【讨论】:

          【解决方案4】:

          docs中所述:

          complete:动画完成后调用的函数,每个匹配元素调用一次。

          这意味着这一行将调用句柄函数 5 次与 5 个匹配的元素。

          $("#first_h1, #first_h3, #sb label, #second_h1, #second_h3").hide("slow", function() {
          

          最简单的解决方案是将渲染代码移到隐藏事件处理程序之外

          【讨论】:

            猜你喜欢
            • 2012-02-26
            • 1970-01-01
            • 1970-01-01
            • 2014-06-18
            • 1970-01-01
            • 1970-01-01
            • 2018-02-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多