Как я могу вызвать функцию в файле js?
У меня есть файл JavaScript AppForm.js
, который я хочу повторно инициализировать после успешного ответа на пост ajax.
Сам файл содержит, среди прочих
(function(namespace, $) {
"use strict";
var AppForm = function() {
// Create reference to this instance
var o = this;
// Initialize app when document is ready
$(document).ready(function() {
o.initialize();
});
};
var p = AppForm.prototype;
p.initialize = function() {
// Init events
this._enableEvents();
this._initRadioAndCheckbox();
this._initFloatingLabels();
this._initValidation();
};
p._enableEvents = function () {
//blah blah blah
e.preventDefault();
};
p._initRadioAndCheckbox = function () {
};
p._initFloatingLabels = function () {
};
p._initValidation = function () {
};
window.materialadmin.AppForm = new AppForm;
}(this.materialadmin, jQuery)); // pass in (namespace, jQuery):
Как я могу это сделать?
$.ajax({
url: path, type: "POST", cache: "false",
dataType: "html",
contentType: "application/json; charset=utf-8",
traditional: true,
data: JSON.stringify(postData)
}).success(function (data) {
$("#products-list").html(data);
//**PERFORM INIT OF JS FILE**
}).error(function (data) {
});
Спасибо Dan, решение довольно близко, но события не работают , так как вызывается e.preventDefault();
.
И вот полный script
(function(namespace, $) {
"use strict";
var AppForm = function() {
// Create reference to this instance
var o = this;
// Initialize app when document is ready
$(document).ready(function() {
o.initialize();
});
};
var p = AppForm.prototype;
// =========================================================================
// INIT
// =========================================================================
p.initialize = function() {
// Init events
this._enableEvents();
this._initRadioAndCheckbox();
this._initFloatingLabels();
this._initValidation();
};
// =========================================================================
// EVENTS
// =========================================================================
// events
p._enableEvents = function () {
var o = this;
// Link submit function
$('[data-submit="form"]').on('click', function (e) {
e.preventDefault();
var formId = $(e.currentTarget).attr('href');
$(formId).submit();
});
// Init textarea autosize
$('textarea.autosize').on('focus', function () {
$(this).autosize({append: ''});
});
};
// =========================================================================
// RADIO AND CHECKBOX LISTENERS
// =========================================================================
p._initRadioAndCheckbox = function () {
// Add a span class the styled checkboxes and radio buttons for correct styling
$('.checkbox-styled input, .radio-styled input').each(function () {
if ($(this).next('span').length === 0) {
$(this).after('<span></span>');
}
});
};
// =========================================================================
// FLOATING LABELS
// =========================================================================
p._initFloatingLabels = function () {
var o = this;
$('.floating-label .form-control').on('keyup change', function (e) {
var input = $(e.currentTarget);
if ($.trim(input.val()) !== '') {
input.addClass('dirty').removeClass('static');
} else {
input.removeClass('dirty').removeClass('static');
}
});
$('.floating-label .form-control').each(function () {
var input = $(this);
if ($.trim(input.val()) !== '') {
input.addClass('static').addClass('dirty');
}
});
$('.form-horizontal .form-control').each(function () {
$(this).after('<div class="form-control-line"></div>');
});
};
// =========================================================================
// VALIDATION
// =========================================================================
p._initValidation = function () {
if (!$.isFunction($.fn.validate)) {
return;
}
$.validator.setDefaults({
highlight: function (element) {
$(element).closest('.form-group').addClass('has-error');
},
unhighlight: function (element) {
$(element).closest('.form-group').removeClass('has-error');
},
errorElement: 'span',
errorClass: 'help-block',
errorPlacement: function (error, element) {
if (element.parent('.input-group').length) {
error.insertAfter(element.parent());
}
else if (element.parent('label').length) {
error.insertAfter(element.parent());
}
else {
error.insertAfter(element);
}
}
});
$('.form-validate').each(function () {
var validator = $(this).validate();
$(this).data('validator', validator);
});
};
// =========================================================================
// DEFINE NAMESPACE
// =========================================================================
window.materialadmin.AppForm = new AppForm;
}(this.materialadmin, jQuery)); // pass in (namespace, jQuery):
Ответы
Ответ 1
Связано с UPDATE 2
Попробуйте зарегистрировать свои события с делегацией:
$(document).on(
'click',
'.ProductOnlyForDemonstation button, .IncludeInMainPage button, .Active button',
function() {
// Your code
}
);
Я полагаю, что вы загружаете что-то и обрабатываете новое содержимое страницы после ответа, поэтому ранее зарегистрированные события не привязаны к новым элементам. При делегировании вы будете работать, даже если элементы были добавлены в DOM динамически (если они совпадают с делегированием селектора), потому что события привязаны к document
и пузырятся с ваших кнопок. Вы можете присоединить событие глубже в DOM, чем document
, , но к элементу, содержащему ваш динамический контент (другими словами: к ближайшему элементу, который не будет переопределен после завершения запроса).
PS. Вы также можете добавить уникальный класс ко всем .ProductOnlyForDemonstation button, .IncludeInMainPage button, .Active button
и делегировать события этому классу (более короткое определение)
Ответ 2
Вы можете обернуть свой код в глобальную функцию.
(function(namespace, $) {
"use strict";
window.main = function() {
var AppForm = function () {
// ...
};
};
window.main(); // you can initialize it here
)(this.materialadmin, jQuery);
И запустите его, если ответ будет успешным.
.success(function (data) {
$("#products-list").html(data);
//**PERFORM INIT OF JS FILE**
window.main();
}).error(function (data) {
});
Изменить. Похоже, вы публикуете метод initialize для глобального объекта. Вы можете просто вызвать этот метод init, когда ответ AJAX завершен.
.success(function (data) {
$("#products-list").html(data);
//**PERFORM INIT OF JS FILE**
window.materialadmin.AppForm.initialize();
}).error(function (data) {
});
Ответ 3
некоторые проверки того, как события будут работать после обратной передачи
1), используя $( "# products-list" ). html (data) удалит все события, связанные с дочерними элементами из списка # products-list.
Итак, либо a) присоединяйте события один раз к "# products-list" только с event-delegation В jQuery, как присоединить события к динамическим элементам html?
или b) повторять события для каждого дочернего элемента после использования $( "# products-list" ). html (data)
2) не используйте .html(), потому что он также удаляет все данные jquery и события для детей. вместо этого обновляйте независимые дочерние элементы.
Ответ 4
У меня была такая же проблема, как и вы. После повторной инициализации событий все события работают некорректно.
Я пробовал много, и, наконец, я нашел проблему. Когда я повторно инициализирую весь элемент управления, все события перегруппируются.
чтобы они не срабатывали должным образом.
поэтому, пожалуйста, отвяжите все события, связанные с вашим контролем, а затем запустите все управляющие агенты и привяжите все события.
Обновленный ответ
если вы используете jQuery 1.7 или onwarads, затем добавьте следующий код:
$(".ProductOnlyForDemonstation, .IncludeInMainPage, .Active").off();
$('[data-submit="form"]').off('click');
$('textarea.autosize').off('focus');
$('.floating-label .form-control').off('keyup change');
//-----------------
//**PERFORM INIT OF JS FILE**
перед этой строкой.
//**PERFORM INIT OF JS FILE**
и вы используете jquery ниже 1.7, затем используйте следующий код:
$(".ProductOnlyForDemonstation, .IncludeInMainPage, .Active").unbind();
$('[data-submit="form"]').unbind('click');
$('textarea.autosize').unbind('focus');
$('.floating-label .form-control').unbind('keyup change');
//-----------------
//**PERFORM INIT OF JS FILE**
перед этой строкой.
//**PERFORM INIT OF JS FILE**
для получения дополнительной помощи, связанной с unbind, нажмите здесь.
для получения дополнительной справки, связанной с отключением здесь.
Я надеюсь, что это поможет.
Ответ 5
Чтобы вызвать функцию, вы должны учитывать следующие моменты:
Функция должна быть определена в том же файле или в файле, который был загружен перед попыткой вызвать его.
Функция должна быть в том же или большем объеме, что и тот, кто пытается ее вызвать.
Итак, следующий пример должен работать:
Вы объявляете функцию fnc1 в first.js, а затем во втором вы можете просто иметь fnc1();
first.js:
function fnc1 (){
alert('test');
}
second.js:
fnc1();
index.html :
<script type="text/javascript" src="first.js"></script>
<script type="text/javascript" src="second.js"></script>
Надеюсь, что это поможет...
Ответ 6
попробуй что-нибудь вроде этого
Код:
Шаг 1: У нас есть следующая функция в файле скриптов /Hello JavaScript:
function HelloWorld() {
//print Hello World
$("#UserMessage").html("Hello World");
}
Шаг 2: Теперь нам нужно вызвать его в другом файле JavaScript в названии Activity. Следуйте приведенному ниже коду:
$.getScript('/Scripts/Hello.js', function () {
HelloWorld();
});
Ответ 7
Вы можете добавить строку namespace.initialize = p.initialize;
в конец вашего кода:
(function(namespace, $) {
"use strict";
/* ....... */
// =================================================
// DEFINE NAMESPACE
// =================================================
namespace.AppForm = new AppForm;
namespace.initialize = p.initialize;
}(this.materialadmin, jQuery)); // pass in (namespace, jQuery):
Затем p.initialize
становится доступным во всем мире как materialadmin.initialize
, и вы можете вызвать его из другого файла следующим образом:
materialadmin.initialize();
Ответ 8
Возможно, два решения
Первое решение
Создайте файл js с вашими функциями, которые будут перезагружаться.
<script language="text/javascript">
function load_js()
{
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'source_file.js';
head.appendChild(script);
}
</script>
И в вашем успехе:
.success(function (data) {
$("#products-list").html(data);
load_js();
}).error(function (data) {
});
2-е решение
Как и первое решение: создайте файл js с вашими функциями, которые будут перезагружаться.
Используйте getScript вместо document.write - он даже позволит выполнить обратный вызов после загрузки файла.
Описание: Загрузите файл JavaScript с сервера с помощью GET HTTP запрос, затем выполните его.
Итак, вы можете попробовать следующее:
.success(function (data) {
$.getScript('your-file.js', function() {
}).error(function (data) {
});
или просто:
jQuery.getScript('my-js.js');
Вы попробуете, и скажите мне, поможет ли это.
Ответ 9
Это должно быть просто, печатая содержимое этого в верхней части вашего ajax url script:
<script src="your-js-to-be-initialized.js"></script>
Ваш код jQuery jQuery останется прежним. Вам просто нужно распечатать script по каждому запросу, чтобы он был повторно инициализирован и привязан к вашим элементам.
$.ajax({
url: path.php, type: "POST", cache: "false",
dataType: "html", contentType: "application/json; charset=utf-8",
traditional: true,
data: JSON.stringify(postData)
}).success(function (data) {
$("#products-list").html(data);
//**PERFORM INIT OF JS FILE**
//path.php should echo/print the <script src="your-js-to-be-initialized.js">
}).error(function (data) {
});
Ответ 10
Я просмотрел вашу историю изменений и увидел, что вы сделали
p._enableEvents = function () {
var o = this;
// Link submit function
$('[data-submit="form"]').on('click', function (e) {
e.preventDefault();
var formId = $(e.currentTarget).attr('href');
$(formId).submit();
});
// Init textarea autosize
$('textarea.autosize').on('focus', function () {
$(this).autosize({append: ''});
});
};
Если это все равно, как вы включаете свои события, я подозреваю, что причиной может быть несколько подписей на фокус формы и текстовую область после повторной инициализации вашего обратного вызова ajax. Я предлагаю попробовать только другие задачи init и исключить привязки событий в вашей функции обратного вызова.
Ответ 11
Попробуйте сделать так:
(function($) {
"use strict";
var materialadmin = {};
var AppForm = function() {
//closure
var self = this;
(function(){
//todo: init events
};)();
//<your AppForm class props here...>
};
materialadmin.Init = function(){
//create instance of AppForm calss for materialadmin object
materialadmin.appForm = new AppForm();
}
return materialadmin;
//*}(jQuery)); // syntax mistake, i'm sorry)).*
})(jQuery);
$(document).ready(function(){
materialadmin.Init();
});
$.ajax({
url: path,
type: "POST",
cache: "false",
dataType: "html",
contentType: "application/json; charset=utf-8",
traditional: true,
data: JSON.stringify(postData),
success: function (data) {
$("#products-list").html(data);
materialadmin.Init();
},
error: function(){
alert('error')}
});
Ответ 12
Поскольку вы используете валидатор jQuery, вы можете использовать Validator
resetForm
, чтобы reset ваша форма.
С этой целью вы можете выставить метод reset
, например:
p.reset = function () {
// Reset managed form
$('.form-validate').data('validator').resetForm();
// Reset custom stuff
this._initRadioAndCheckbox();
this._initFloatingLabels();
};
Обратите внимание, что для корректной формы reset после отправки вашего запроса вам необходимо изолировать привязку события от элемента init, например, следующее связывание событий должно перемещаться от _initFloatingLabels
до _enableEvents
:
// Link submit function
$('[data-submit="form"]').on('click', function (e) {
e.preventDefault();
var formId = $(e.currentTarget).attr('href');
$(formId).submit();
});
Наконец, вы просто должны вызвать window.materialadmin.AppForm.reset()
в своем обратном вызове запроса POST.