javascript jQuery UI:通过 AJAX 加载内容后重新初始化函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19433766/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery UI: Re-initializing a function after loading content via AJAX
提问by amthomas2112
I've been searching all over for an answer to this question for a few days now, and while I have found most of the answer to my problem, there's still one piece of my code that is not working as it did before adding AJAX calls.
几天来,我一直在四处寻找这个问题的答案,虽然我已经找到了问题的大部分答案,但仍有一段代码无法像添加 AJAX 调用之前那样工作.
Some background: I am creating a web app to serve as an RPG character generator. One of the first things that happens is I create jQuery UI spinner widgets to adjust stat scores. On the stop event, my code runs a function that checks the current number against a switch case to set a value to how many points are added or subtracted from an initial pool (Point-Buy system, for anyone who knows about these things):
一些背景:我正在创建一个 Web 应用程序来充当 RPG 角色生成器。发生的第一件事是我创建了 jQuery UI 微调器小部件来调整统计分数。在停止事件中,我的代码运行一个函数,该函数根据 switch 情况检查当前数字,以设置一个值来表示从初始池中添加或减去的点数(点买系统,对于了解这些事情的任何人):
function calcPtsLeft() {
var ptssum = new Number();
var ptsmax = new Number($("#maxpoints").val());
var pbstr = pointBuy($strsc.val());
var pbdex = pointBuy($dexsc.val());
var pbcon = pointBuy($consc.val());
var pbint = pointBuy($intsc.val());
var pbwis = pointBuy($wissc.val());
var pbcha = pointBuy($chasc.val());
var ptssum = pbstr + pbdex + pbcon + pbint + pbwis + pbcha;
ptsleft = ptsmax - ptssum;
$("#ptsleft").val(ptsleft);
};
calcPtsLeft();
This code functioned properly, up until I decided to use AJAX calls to dynamically load various pages into a #content div. After making the AJAX call to load my character generator, my widgets didn't show up at all. I found that this was due to a delegation problem, so I collected all of my widget initialization into a function:
这段代码运行正常,直到我决定使用 AJAX 调用将各种页面动态加载到 #content div 中。在进行 AJAX 调用以加载我的字符生成器后,我的小部件根本没有出现。我发现这是由于委托问题,所以我将所有小部件初始化收集到一个函数中:
function initGenWidgets() {
//sets CSS for input/label items from jQuery UI set
$("#slider input:text, #slider label, #remaining input:text, #remaining label, #charName, #charAge")
.addClass("ui-spinner ui-spinner-input");
//initialize jQuery UI button widget
$("button").button();
//initialize jQuery UI radio buttonset widget
$("#genderbuttons").buttonset();
//initialize jQuery UI menu widget
$("#raceradio").menu();
//initialize jQuery UI vertical tabs
$("#char-gen").tabs().addClass("ui-tabs-vertical ui-helper-clearfix");
$("#char-gen li").removeClass("ui-corner-top").addClass("ui-corner-left");
//initialize jQuery UI spinner widget for age
$("#charAge").spinner({
icons: {
down: "ui-icon-minus",
up: "ui-icon-plus"
}
});
//initialize jQuery UI spinner widget for stats
$(".statspinner").spinner({
min : 7,
max : 18,
icons : {
down : "ui-icon-minus",
up : "ui-icon-plus"
},
stop: function(event, ui) {
calcPtsLeft();
}
});
//initialize jQuery UI slider widget for point-buy allotment
$("#pointslider").slider({
value: 20,
min: 15,
max: 40,
step: 5,
slide: function(event, ui) {
$("#maxpoints").val(ui.value);
calcPtsLeft();
}
});
};
I now make the AJAX call as follows:
我现在按如下方式进行 AJAX 调用:
//function to load php files into content div
function loadContent($page){
$("#content").load($page+' > *', function(response, status){
success: initGenWidgets();
});
};
//nav links load files into content div
$(".menulink").on("click", function(e){
e.preventDefault();
loadContent($(this).attr("href"));
});
Everything seems to load fine, but when I test the widgets, it seems that my spinners no longer execute the calcPtsLeft()
function on stop. The slider works to update the #ptsLeft value after I slide it (going to fix that later), but the spinners do not update the value at all.
一切似乎都加载良好,但是当我测试小部件时,似乎我的微调器不再calcPtsLeft()
在停止时执行该功能。滑块在我滑动后更新 #ptsLeft 值(稍后将修复),但微调器根本不更新该值。
What am I doing wrong here, or not doing at all here? Any help would be greatly appreciated.
我在这里做错了什么,或者在这里根本没有做?任何帮助将不胜感激。
回答by MackieeE
jQuery .load()
:
jQuery .load()
:
Script Execution
脚本执行
When calling
.load()
using a URL without a suffixed selector expression, the content is passed to .html()
prior to scripts being removed. This executes the script blocks before they are discarded. If.load()
is called with a selector expression appended to the URL, however, the scripts are stripped out prior to the DOM being updated, and thus are not executed. An example of both cases can be seen below
.load()
使用不带后缀选择器表达式的 URL 进行调用时,内容将传递给 .html()
在删除脚本之前。这会在脚本块被丢弃之前执行它们。但是,如果.load()
使用附加到 URL 的选择器表达式调用,脚本会在 DOM 更新之前被剥离,因此不会被执行。可以在下面看到这两种情况的示例
A small but important segment of the docs for .load()
! If you really wanted to execute them, you'll probably have to do some sort of eval()
, or discard the .selector
文档的一小部分但很重要的部分.load()
!如果您真的想执行它们,您可能必须执行某种操作eval()
,或者丢弃.selector
Example:
例子:
Here, any JavaScript loaded into #a
as a part of the document will successfully execute.
在这里,#a
作为文档一部分加载的任何 JavaScript都将成功执行。
$( "#a" ).load( "article.html" );
However, in the following case, script blocks in the document being loaded into #b
are stripped out and notexecuted:
但是,在以下情况下,正在加载的文档中的脚本块将被#b
剥离而不执行:
$( "#b" ).load( "article.html #target" );
Possible Solution
可能的解决方案
Well, after testing - I decided to actually take the step of adding the functions to the window, simply because it's the best way of carrying across functions & methods via many scripts. This, hopefully fixes have undefined functions being declared, because you're in a different script & namespace.
好吧,经过测试 - 我决定实际采取将函数添加到窗口的步骤,仅仅是因为这是通过许多脚本跨函数和方法的最佳方式。这个,希望修复已经声明了未定义的函数,因为你在不同的脚本和命名空间中。
Main.php
主文件
<script>
//Create Rgp Object
var Rgp = {
calcPtsLeft : function() {
console.log( 'Calculate Points' );
},
addPoints : function() {
//Some addPoints Function
}
};
//Add Object to Window
window.Rgp = Rgp;
$('#begin').on('click', function() {
$("#content").load( 'someScript.js', function( response, status ){
success: initGenWidgets();
});
});
</script>
someScript.js
someScript.js
<script>
function initGenWidgets() {
$("#pointslider").slider({
value: 20,
min: 15,
max: 40,
step: 5,
slide: function(event, ui) {
$("#maxpoints").val(ui.value);
Rgp.calcPtsLeft(); //Prints 'Calculate Points'
}
});
}
</script>