在application.js中,我通过ajax调用在页面上编译了所有“主题”,然后当单击一个时,所有信息都会显示在屏幕上。一切都在开发中很好,但在生产中我得到500服务器错误。
在尝试调试时,我注意到控制台正在使用.onclick调用记录20次。为什么会发生这种情况,是否有任何理由在生产中返回500错误(heroku)?
我把** **放在3个console.logs周围。
if(window.location.pathname === "/topics") {
$('.actions').click(function(e) {
console.log("submit");
})
$.ajax({
url: '/topics',
dataType: 'json',
type: 'GET',
success: function(result) {
console.log(result);
for(var i = 0; i < result.length; i++) {
var title = result[i].title;
var level = result[i].level;
var id = result[i].id;
var favlink = '/topics/' + id + '/favorite';
var link = '/topics/' + id;
var topicInfo = {title: title, link: link};
var template = compiledTopics(topicInfo);
$('.topic-wrapper').append(template);
$('.listing-topics, .favorite-topic-title').click(function(e){
e.preventDefault();
if( $(this).hasClass("favorite-topic-title")) {
var heartClass = "favorited_heart_icon"
}
else if( $(this).hasClass("listing-topics")) {
var heartClass = "unfavorited_heart_icon";
$('html, body').animate({ scrollTop: 0 }, 'fast');
}
**console.log(this);**
$.ajax({
url: this,
dataType: "json",
type: 'GET',
success: function(result) {
var id = result.id;
var title = result.title;
var body = result.body;
var level = result.level
**console.log(level);**
//SHOW TOPIC and FAVTOPIC AS POPUP WHEN CLICKED
//Add proper favorite icon.
var favlink = '/topics/' + id + '/favorite';
**console.log(heartClass);**
var topicInfo = {title: title, body: body, heartClass: heartClass};
var template = compiled(topicInfo);
$('.topic-wrapper').append(template);
//CLOSE TOPIC WHEN CLICKING THE GREY SURROUNDING BOX - topicClose
$('.topicClose').click(function(e) {
$('.topicClose').css("display", "none");
$('.show_topic').css("display", "none");
})
//FAVORITE TOPIC
//ADD TO FAV TOPICS LIST
$(".unfavorited_heart_icon, .favorited_heart_icon").click(function(e) {
e.preventDefault();
//onclick - change colors of heart
if ( $(this).hasClass("favorited_heart_icon")) {
$(this).removeClass("favorited_heart_icon");
$(this).addClass("unfavorited_heart_icon");
urlEnd = '/unfavorite';
}
else if ( $(this). hasClass("unfavorited_heart_icon")) {
$(this).removeClass("unfavorited_heart_icon");
$(this).addClass("favorited_heart_icon");
urlEnd = '/favorite';
}
// console.log('/topics/favorite/' + id);
$.ajax({
url: '/topics/' + id + urlEnd,
type: 'POST',
success: function(result) {
location.reload();
}
})
});
},
error: function(err) {
console.log(err);
}
})
});
};
},
error: function(err) {
}
});
位于同一个js文件的底部:
var listingSource = $("#listingTopics").html();
var compiledTopics = Handlebars.compile(listingSource);
主题车把模板:
<script id="listingTopics">
<div>
<a href={{link}} class="listing-topics">{{title}}</a>
</div>
</script>
提前致谢!
编辑**
我也试过了:
$.ajax({
url: '/topics',
dataType: 'json',
type: 'GET',
success: function(result) {
for(var i = 0; i < result.length; i++) {
var title = result[i].title;
var level = result[i].level;
var id = result[i].id;
var favlink = '/topics/' + id + '/favorite';
var link = '/topics/' + id;
var topicInfo = {title: title, link: link};
var template = compiledTopics(topicInfo);
$('.topic-wrapper').append(template).click(function(e) {
e.preventDefault();
console.log($(this))
});
};
},
答案 0 :(得分:1)
我认为通过将这些侦听器从循环中取出并使用委托策略定义它们,可以解决许多分配多个事件侦听器的问题。
我会在概念上尝试类似于:
的东西function getTopicJSON_Success(result){
console.log(result);
for(var i = 0; i < result.length; i++) {
var title = result[i].title;
var level = result[i].level;
var id = result[i].id;
var favlink = '/topics/' + id + '/favorite';
var link = '/topics/' + id;
var topicInfo = { title: title, link: link };
var template = compiledTopics(topicInfo);
$('.topic-wrapper').append(template);
}
}
function getJSON_Error(err){
console.log(err);
}
if(window.location.pathname === "/topics") {
$('.actions').click(function(e) {
console.log("submit");
});
$('.topic-wrapper').on("click", '.listing-topics, .favorite-topic-title', function(e){
e.preventDefault();
// =========================
// Note at this point "this" is the element that was clicked.
// in the ajax requrest below we will want to use $this.attr("href").
// =========================
console.log(this);
// =========================
var $this = $(this);
var heartClass;
if( $this.hasClass("favorite-topic-title") ) {
heartClass = "favorited_heart_icon"
} else if( $this.hasClass("listing-topics") ) {
heartClass = "unfavorited_heart_icon";
$("body").animate({ scrollTop: 0 }, 'fast');
}
// =========================
// Note: could be "null".
// Did you want one or the other specifically and not the posibility of null?
// =========================
console.log(heartClass);
// =========================
var getListJSON_Success = function(result){
var id = result.id;
var title = result.title;
var body = result.body;
var level = result.level
console.log(level);
//SHOW TOPIC and FAVTOPIC AS POPUP WHEN CLICKED
//Add proper favorite icon.
var favlink = '/topics/' + id + '/favorite';
var topicInfo = {title: title, body: body, heartClass: heartClass};
var template = compiled(topicInfo);
$('.topic-wrapper').append(template);
//CLOSE TOPIC WHEN CLICKING THE GREY SURROUNDING BOX - topicClose
$('.topicClose').click(function(e) {
$('.topicClose').css("display", "none");
$('.show_topic').css("display", "none");
});
//FAVORITE TOPIC
//ADD TO FAV TOPICS LIST
};
$.ajax({
url: $this.attr("href"),
dataType: "json",
type: 'GET',
success: getListJSON_Success,
error: getJSON_Error
})
});
$('.topic-wrapper').on("click", ".unfavorited_heart_icon, .favorited_heart_icon", function(e) {
e.preventDefault();
var $this = $(this);
var urlEnd;
if ( $this.hasClass("favorited_heart_icon") ) {
$this.removeClass("favorited_heart_icon");
$this.addClass("unfavorited_heart_icon");
urlEnd = '/unfavorite';
} else if ( $this. hasClass("unfavorited_heart_icon") ) {
$this.removeClass("unfavorited_heart_icon");
$this.addClass("favorited_heart_icon");
urlEnd = '/favorite';
}
$.ajax({
url: '/topics/' + $this.attr("id") + urlEnd,
type: 'POST',
success: function(result) { location.reload(); },
error: getJSON_Error
});
});
$.ajax({
url: '/topics',
dataType: 'json',
type: 'GET',
success: getTopicJSON_Success,
error: getJSON_Error
});
}
答案 1 :(得分:0)
我猜测results
约有20个项目。当您在for循环中创建click
事件处理程序时,将其绑定到类.listing-topics, .favorite-topic-title
。单击元素时,它会继续并触发单击事件(因为结果数组中有20个项目,因此会触发20次)。我怀疑这是发生了什么,但需要看到它来验证。你有JSFiddle吗?
要解决此问题,请更改绑定事件处理程序的方式。您需要将其范围限定为类或元素的特定实例,以便事件可以单独触发而不是一次触发。
SAMPLE SCENARIO
var results = ["1", "2", "3"];
//How you're currently doing it
for (var i = 0; i < results.length; i++) {
$('#container').append($('<div />', {text: results[i], class:'test-class'}));
$('.test-class').click(function () {
console.log($(this).text());
});
}
//Solution
for (var i = 0; i < results.length; i++) {
$('#container').append($('<div />', {text: results[i], class:'test-class'}).click(function () {
console.log($(this).text());
}));
}
我已经创建了这个场景的简单复制(与你的一致),以帮助更好地解释正在发生的事情。基本上,一次性(按类)绑定所有事件的instaed,在创建它时将它绑定到元素。
JSFIDDLE: https://jsfiddle.net/ncrxekmq/
更新代码
if(window.location.pathname === "/topics") {
$('.actions').click(function(e) {
console.log("submit");
})
$.ajax({
url: '/topics',
dataType: 'json',
type: 'GET',
success: function(result) {
console.log(result);
for(var i = 0; i < result.length; i++) {
var title = result[i].title;
var level = result[i].level;
var id = result[i].id;
var favlink = '/topics/' + id + '/favorite';
var link = '/topics/' + id;
var topicInfo = {title: title, link: link};
var template = compiledTopics(topicInfo);
$('.topic-wrapper').append(template);
//use $.each(index, item) to loop through all of your elements and bind the click event individually instead of in one go.
$('.listing-topics, .favorite-topic-title').each(function (index, item) {
$(item).click(function(e){
e.preventDefault();
if( $(this).hasClass("favorite-topic-title")) {
var heartClass = "favorited_heart_icon"
}
else if( $(this).hasClass("listing-topics")) {
var heartClass = "unfavorited_heart_icon";
$('html, body').animate({ scrollTop: 0 }, 'fast');
}
**console.log(this);**
$.ajax({
url: this,
dataType: "json",
type: 'GET',
success: function(result) {
var id = result.id;
var title = result.title;
var body = result.body;
var level = result.level
**console.log(level);**
//SHOW TOPIC and FAVTOPIC AS POPUP WHEN CLICKED
//Add proper favorite icon.
var favlink = '/topics/' + id + '/favorite';
**console.log(heartClass);**
var topicInfo = {title: title, body: body, heartClass: heartClass};
var template = compiled(topicInfo);
$('.topic-wrapper').append(template);
//CLOSE TOPIC WHEN CLICKING THE GREY SURROUNDING BOX - topicClose
$('.topicClose').click(function(e) {
$('.topicClose').css("display", "none");
$('.show_topic').css("display", "none");
})
//FAVORITE TOPIC
//ADD TO FAV TOPICS LIST
$(".unfavorited_heart_icon, .favorited_heart_icon").click(function(e) {
e.preventDefault();
//onclick - change colors of heart
if ( $(this).hasClass("favorited_heart_icon")) {
$(this).removeClass("favorited_heart_icon");
$(this).addClass("unfavorited_heart_icon");
urlEnd = '/unfavorite';
}
else if ( $(this). hasClass("unfavorited_heart_icon")) {
$(this).removeClass("unfavorited_heart_icon");
$(this).addClass("favorited_heart_icon");
urlEnd = '/favorite';
}
// console.log('/topics/favorite/' + id);
$.ajax({
url: '/topics/' + id + urlEnd,
type: 'POST',
success: function(result) {
location.reload();
}
})
});
},
error: function(err) {
console.log(err);
}
})
});
});
};
},
error: function(err) {
}
});