Это контекст:
У меня есть скрипт, 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, в нерабочих нет
По предложению страныВыберите автора Марк, я повторил тест на более простой странице и обнаружил, что он работает как локально (добавление элемента при нажатии кнопки), так и при вызове 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>