2017-09-22 34 views
0

我正在構建一個Web應用程序,用戶可以在其中鍵入任何關鍵詞或語句,並使用維基百科API獲取二十個來自維基百科的結果。 AJAX工作得很好。當Web應用程序從維基百科獲取數據時,它應該將每個結果顯示爲動態創建的DIV。單擊事件多次觸發的方法

會發生什麼情況是,當點擊事件被觸發時,二十個DIV被創建五次,總共有一百個。我不知道爲什麼,但正如你可以在下面的代碼片段中看到的那樣,Web應用程序爲每個DOM元素創建了20個DIV,當點擊事件被觸發時,這些DOM元素已被隱藏(通過.hide)。

這裏的是代碼:

function main() { 
 

 
function positive() { 
 

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

 
     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() { 
 
\t   var data = JSON.parse(request.responseText); 
 
\t   render(data); 
 
\t   //console.log(data); 
 
     } 
 
     request.send(); 
 
    } 
 

 
} 
 

 
function render(data) { 
 

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

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

 
     //} 
 
    }); 
 
     
 
} 
 

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

 
} 
 

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

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

 
.align { 
 
\t text-align: center; 
 
} 
 

 
#first_h1 { 
 
\t margin-top: 30px; 
 
} 
 

 
#first_h3 { 
 
\t margin-bottom: 30px; 
 
} 
 

 
#sb { 
 
\t margin-bottom: 10px; 
 
} 
 

 
#second_h1 { 
 
\t margin-top: 30px; 
 
} 
 

 
#second_h3 { 
 
\t margin-bottom: 30px; 
 
} 
 

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

 
\t <h1 class="align" id="first_h1">Wikipedia Viewer</h1> 
 
\t <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> 
 

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

 
\t <h1 class="align" id="second_h1">...Or...</h1> 
 
\t <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> 
 

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

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

我使代碼更易於閱讀通過擦除for循環。正如你所看到的,即使只有一個結果,它會顯示五次。

你知道爲什麼會發生嗎? 感謝

回答

1

行:

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

說,在這個「清單」的每一個元素,隱藏要素和運行的代碼塊隱藏後。

+0

完美外的代碼,我明白了。現在代碼正常工作 – Dema

0
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.. 

} 
1

此代碼是罪魁禍首:

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

回調函數調用了五次,每一個ID爲所有的上市,不是一次,正如您所料。

一種解決方法是創建一個類(比方說, 「hideme」),將其應用到要隱藏的每個元素,並寫上:

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

感謝您的解決方法小貼士 – Dema

+0

不客氣。 –

0

正如docs描述:

complete:動畫完成後調用的函數,每匹配元素調用一次。

這意味着這行將調用5次與5個匹配元素的句柄函數。

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

最簡單的解決方案正在渲染的隱藏事件處理程序