这是上下文:
我有一个脚本countrySelect.min.js,该脚本已加载到php页面的页眉中(在其他位置,它不起作用,因此请假定这是正确的脚本)
<script src="<?php echo base_url(); ?>assets/owlcarousel/owl.carousel.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>assets/js/bootstrap.min.js"></script>
<script type="text/javascript" src="<?php echo base_url('assets/js/commonFunctions.js'); ?>"></script>
<link rel="stylesheet" href="<?php echo base_url('assets/css/countrySelect.css'); ?>">
<script type="text/javascript" src="<?php echo base_url('assets/js/countrySelect.min.js'); ?>"></script>
<link rel="stylesheet" href="<?php echo base_url('assets/css/countrySelectorStyle.css'); ?>">
此脚本在函数( initializeLeafletItems )中使用,以将正确的位置应用于某些国家/地区选择下拉框,调用该函数的“ countrySelect ”功能到用 $(“#country_selector” + temp_offer_id)
标识的对象function initializeLeafletItems(offers){
leaflets_info = {};
var temp_product_info_id;
var temp_product_info = {};
var temp_offer_id;
var temp_default_country_code;
const observer = new MutationObserver(function(mutationsList, observer) {
[...]
)};
[...]
for(var index in offers){
if(offers[index]['package_leaflets']){
temp_default_country_code = offers[index]['defaultCountry'];
temp_offer_id = offers[index]['id'];
$("#country_selector"+temp_offer_id).countrySelect({
defaultCountry: temp_default_country_code,
onlyCountries: offers[index]['countries_list'],
responsiveDropdown: true,
});
[...]
}
}
此函数几乎在文档的结尾,但在$(document).ready(function)语句之外。它工作正常,没有任何错误。
initializeLeafletItems(<?php echo json_encode($offers); ?>);
问题:如果用户单击“显示更多”按钮,则在向页面结果中添加新元素时将调用相同的功能。更具体地说,它在ajax语句内部被调用
function show_offers(render, from_item, to_item, products_id_list, searchedGeneric, searchedMade, searchedCountries, searchedFormats, searchedCurrency, keywords_id){
if (render == 'PCRender') {
$.ajax({
method:'POST',
url: ajax_url+'frontController/addRenderScreenOffers',
data:{
[...]
},
dataType:'json',
success:function(res)
{
if(res['rendered_PC_screen_offers'] != 'empty'){
$("#offers-product tbody").append(res['rendered_PC_screen_offers']);
from_item = to_item + 1;
to_item = to_item + 10;
$("#show_more_button").replaceWith('[...] )">Show More</button>');
initializeLeafletItems(res['offers']['offers']);
在这种情况下,我会收到此错误
Uncaught TypeError: $(...).countrySelect is not a function
好像该函数不在show_offers函数或ajax调用的范围内。我觉得这很奇怪;但是,当浏览器调试器停止运行时,我试图查看看到的范围,并且似乎脚本及其功能已经存在,请查看以下屏幕截图:
我还没有找到很多类似情况的参考文献(当然不是明确的参考文献),因此确实有帮助的想法。在不太相似的情况下,我阅读了一些有人建议在ajax调用内重新加载脚本的信息。即使我不知道它是否有效,因为我还没有尝试过,我认为既然脚本已经加载到文档中,那么应该在该函数的两个调用中都引用它。这是真的吗?
更新12/04/2020
将应用对象的控制台登录到控制台。countrySelect我可以观察到在工作情况下(下图左侧)有一个链接的countrySelect插件,在不工作的情况下没有
在遵循countrySelect作者Mark的建议之后,我在一个简单的页面上重复了该测试,发现该测试在本地(单击按钮时添加一个元素)和ajax调用均有效。这里遵循控制器和查看器的代码;因此,我也尝试在不工作的页面上添加简单的测试,方法是单击没有ajax的按钮来添加输入元素。即使在这种情况下,它也不起作用(但仍然可以在同一页面的首次下载中的元素上起作用)。任何想法?在该页面上似乎丢失了某些东西或无法很好地进行交互。
在简单页面(https://www.pharmacomparison.com/frontController/countrySelectTest/)上显示工作代码
控制器:
function countrySelectTest(){
$this->load->view('countrySelectTest');
}
function countrySelectTestresult(){
$random = mt_rand(0,999999999);
$res['html_text'] = '<input type="text" id="country_selector_ajax'.$random.'" name="country_selector_ajax">';
$res['state'] = 'success';
$res['random'] = $random;
echo json_encode($res);
}
查看者
<head>
<meta charset="utf-8">
<title>Country Select JS</title>
<link rel="stylesheet" href="build/css/countrySelect.css">
<link rel="stylesheet" href="build/css/demo.css">
<link rel="stylesheet" href="<?php echo base_url('assets/css/countrySelect.css'); ?>">
<link rel="stylesheet" href="<?php echo base_url('assets/css/demo.css'); ?>">
<script type="text/javascript" src="<?php echo base_url(); ?>assets/js/jquery.js"></script>
<script type="text/javascript" src="<?php echo base_url('assets/js/countrySelect.min.js'); ?>"></script>
</head>
<body>
<h1>Country Select JS</h1>
<form>
<div class="" id="country">
<input id="country" type="text">
<label for="country_selector" style="display:none;">Select a country here...</label>
</div>
<button type="submit" style="display:none;">Submit</button>
</form>
<button type="submit" id="local_test">Local Test</button>
<button type="submit" id="ajax_test">Ajax Test</button>
<!-- Load jQuery from CDN so can run demo immediately -->
<script>
$("#country").countrySelect({
// defaultCountry: "jp",
// onlyCountries: ['us', 'gb', 'ch', 'ca', 'do'],
// responsiveDropdown: true,
preferredCountries: ['ca', 'gb', 'us']
});
</script>
<script>
// Make sure we don't run this until after everything else has been loaded.
// Using the document click handler ensures that everything else is setup first,
// which ensures we're not cheating and adding our new element before the
// plugin attaches to form elements the first time.
$('#local_test').on('click', function(){
// Step 1: Create a new element from a simulated AJAX request
var newInput = $('<input type="text" id="country_selector_local" name="country_selector_local">');
// Step 2: Add the new element to the page
$('form').append(newInput);
// Step 3: Run the plugin on the new element
$('#country_selector_local').countrySelect({ defaultCountry: 'au' });
// Step 4: Profit!
});
$('#ajax_test').on('click', function(){
//the URL return te same content of previous newInput
$.ajax({
url: 'https://www.pharmacomparison.com/frontController/countrySelectTestResult/',
type: "POST",
enctype: 'multipart/form-data',
data: {
product_info_id: 'test'
},
method: 'Post',
dataType: 'json',
success: function(response) {
if(response.state=='error'){
alert(response.msg);
}
if(response.state=='success'){
// Step 2: Add the new element to the page
$('form').append(response.html_text);
// Step 3: Run the plugin on the new element
$('#country_selector_ajax'+response['random']).countrySelect({ defaultCountry: 'au' });
// Step 4: Profit!
}
},
error: function(xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
alert("The request returned an error, please alert the site administrators (" + status +").");
}
});
});
</script>
</body>
答案 0 :(得分:1)
问题是您在initializeLeafletItems(<?php echo json_encode($offers); ?>);
调用结束后重新初始化了jquery。这将重置jquery上下文并从$ .fn
让我解释一下
和
看到它们在#56、58和5134行上。
initializeLeafletItems(<?php echo json_encode($offers); ?>);
在#4701行
现在,当您在第4701行运行此代码时,发生的情况是country select被附加到先前加载的一个jquery上,并且可以正常工作。然后,将jquery重置,并从jquery context
中删除countrySelect,因此,页面完全加载后,您将无法使用countrySelect。
解决方案。
应该只有一个jquery调用(不是强制性的好习惯,它会减少页面加载时间)
在<head>
顶部或<body>
之前的某个位置加载jquery,然后从#5134行中删除。
在#5134之后加载countrySelect.min.js并将initializeLeafletItems(<?php echo json_encode($offers); ?>);
移动到document.ready
在所有jquery加载后执行刚刚加载countrySelect.min.js的操作。
仅供参考:您正在加载的所有jquery的版本均为v3.4.1。因此,我看不出有任何特定原因可将其加载三次。如果我错了请纠正我。
希望对您有帮助。