#javascript #jquery
#javascript #jquery
Вопрос:
У меня есть файл JavaScript здесь http://www.problemio.com/js/problemio.js и я пытаюсь поместить в него некоторый код jQuery, который выглядит примерно так:
$(document).ready(function()
{
queue = new Object;
queue.login = false;
var $dialog = $('#loginpopup')
.dialog({
autoOpen: false,
title: 'Login Dialog'
});
var $problemId = $('#theProblemId', '#loginpopup');
$("#newprofile").click(function ()
{
$("#login_div").hide();
$("#newprofileform").show();
});
// Called right away after someone clicks on the vote up link
$('.vote_up').click(function()
{
var problem_id = $(this).attr("data-problem_id");
queue.voteUp = $(this).attr('problem_id');
voteUp(problem_id);
//Return false to prevent page navigation
return false;
});
var voteUp = function(problem_id)
{
alert ("In vote up function, problem_id: " problem_id );
queue.voteUp = problem_id;
var dataString = 'problem_id=' problem_id 'amp;vote= ';
if ( queue.login = false)
{
// Call the ajax to try to log in...or the dialog box to log in. requireLogin()
}
else
{
// The person is actually logged in so lets have him vote
$.ajax({
type: "POST",
url: "/problems/vote.php",
dataType: "json",
data: dataString,
success: function(data)
{
alert ("vote success, data: " data);
// Try to update the vote count on the page
//$('p').each(function()
//{
//on each paragraph in the page:
// $(this).find('span').each()
// {
//find each span within the paragraph being iterated over
// }
//}
},
error : function(data)
{
alert ("vote error");
errorMessage = data.responseText;
if ( errorMessage == "not_logged_in" )
{
//set the current problem id to the one within the dialog
$problemId.val(problem_id);
// Try to create the popup that asks user to log in.
$dialog.dialog('open');
alert ("after dialog was open");
// prevent the default action, e.g., following a link
return false;
}
else
{
alert ("not");
}
} // End of error case
}
}); // Closing AJAX call.
};
$('.vote_down').click(function()
{
alert("down");
problem_id = $(this).attr("data-problem_id");
var dataString = 'problem_id=' problem_id 'amp;vote=-';
//Return false to prevent page navigation
return false;
});
$('#loginButton', '#loginpopup').click(function()
{
alert("in login button fnction");
$.ajax({
url:'url to do the login',
success:function() {
//now call cote up
voteUp($problemId.val());
}
});
});
});
</script>
Есть две причины, по которым я пытаюсь это сделать:
1) Я предполагаю, что это просто хорошая практика (надеюсь, будет легче отслеживать мои глобальные переменные и т. Д. 2) Что еще более важно, я пытаюсь вызвать функцию voteUp(someId) в исходном коде из problemio.js файл, и я получаю сообщение об ошибке, что это неопределенная функция, поэтому я решил, что мне больше повезло бы вызвать эту функцию, если бы она была в глобальной области видимости. Я прав в своем подходе?
Итак, могу ли я просто скопировать / вставить код, который я поместил в этот вопрос, в problemio.js файл, или я должен удалить определенные его части, такие как открывающие / закрывающие теги? Как насчет функции document.ready()? Должен ли я просто иметь один из них в глобальном файле? Или у меня их должно быть несколько, и это не повредит?
Спасибо!!
Комментарии:
1.
if ( queue.login = false)
неверно, вам нужны два==
для сравнения. Кроме того, используйте{}
вместоnew Object()
и передайте объект вместо строки в ajaxdata
. И последнее, но не менее важное: обратите внимание, что есть.data(name[, value])
, который вы можете использовать вместо.attr('data-name')
.2. @ThiefMaster хороший момент. Исправлено == в моем коде.
3. @ThiefMaster Я немного новичок в JS, в чем разница между использованием синтаксиса {} и new Object() ? Как именно я должен его изменить?
4. В основном это выглядит лучше.
var queue = {};
или дажеvar queue = { login: false };
Ответ №1:
1) Я предполагаю, что это просто хорошая практика (надеюсь, будет легче отслеживать мои глобальные переменные и т. Д.
Да и нет, теперь у вас есть «глобальные» переменные в одном месте, но вероятность того, что вы столкнетесь с «глобальными» переменными (то есть с теми, которые определены браузером), увеличилась на 100% 🙂
Например, скажем, вы решили вызвать переменную location
, как только вы присваиваете этой переменной значение, браузер решает перейти на другой URL, потому location
что это зарезервированное слово для перенаправления.
Решение этой проблемы заключается в использовании пространства имен, как описано здесь
2) Что еще более важно, я пытаюсь вызвать функцию voteUp(someId) в исходном коде из problemio.js файл, и я получаю сообщение об ошибке, что это неопределенная функция, поэтому я решил, что мне больше повезло бы вызвать эту функцию, если бы она была в глобальной области видимости. Я прав в своем подходе?
Вот пример использования пространства имен, который вызовет voteUp
функцию:
(function($) {
var myApp = {};
$('.vote_up').click(function(e) {
e.preventDefault();
myApp.voteUp();
});
myApp.voteUp = function() {
console.log("vote!");
}
})(jQuery);
Как насчет функции document.ready()? Должен ли я просто иметь один из
них в глобальном файле? Или у меня их должно быть несколько, и это
не повредит?
У вас может быть столько слушателей document.ready, сколько вам нужно, вы не переопределяете document.ready вы прослушиваете запуск этого события, а затем определяете, что произойдет. Вы могли бы даже иметь их в отдельных файлах javascript.
Комментарии:
1. спасибо — я переработал код, чтобы он был в одном файле, но я все еще получаю ошибку undefined function. Не могли бы вы взглянуть на обновленный код, с помощью которого я собираюсь изменить исходный ответ?
2. на самом деле, чтобы упростить задачу, вот как я определяю функцию: var voteUp = function(problem_id) { … и это выше его вызова, который не определен. Это просто неправильный синтаксис? В вашем предложении он немного отличается. Теперь убедитесь, каковы последствия между различиями.
3. Вам не нужно использовать
var
для объявления функции, вы также можете написатьfunction voteUp(){}
или, если вы действительно хотите сделать его глобальнымwindow.voteUp = function(){}
. Если он все еще не определен при использовании метода window.voteUp, значит, происходит что-то еще (проблемы с загрузкой).
Ответ №2:
Убедитесь, что ваша страница находит файл jquery, ПРЕЖДЕ чем этот файл будет включен в страницу. Если jquery там нет, сначала вы получите function not defined . В противном случае у вас могут быть другие вещи, противоречащие вашему jquery, я бы изучил jquery noConflict .
var j = jQuery.noConflict();
как показано здесь:
http://api.jquery.com/jQuery.noConflict/
Счастливый хаксин
_writeowl
Комментарии:
1. в этом уже есть jQuery problemio.js код. Так что неопределенное не от этого. Я предполагаю, что problemio.js код не знает о voteUp() на странице, где все происходит, но я не уверен, как увеличить область действия функции voteUp().
2. -1, noConflict предотвращает нарушение jQuery других вещей, которые могут с ним столкнуться. поэтому, если его код jQuery не работает, этот вызов не исправит это (а скорее сломает его, пока он не обернет свой код в функцию
$
, которая снова станет доступной)
Ответ №3:
Расширение того, что уже предоставил KreeK: нет необходимости определять ваше «MyApp» в функции document ready. Без тестирования я не знаю, является ли это потенциальным источником проблем с областью действия. Однако я МОГУ сказать, что приведенный ниже шаблон не будет иметь проблем с областью действия. Если это не работает, возможно, проблема с неопределенностью связана с загрузкой скрипта (например, загрузка в правильном порядке), а не с областью действия.
var myApp = myApp || {}; // just adds extra insurance, making sure "myApp" isn't taken
myApp.voteUp = function() {
console.log("vote!");
}
$(function() { // or whatever syntax you prefer for document ready
$('.vote_up').click(function(e) {
e.preventDefault();
myApp.voteUp();
});
});