JQuery не работает в живой среде - PullRequest
4 голосов
/ 26 марта 2012

У меня есть следующий код, который отлично работает в jsfiddle - http://jsfiddle.net/darkajax/FHZBy/

Я перенес код на страницу, где мне нужно использовать код, и назначил правильные идентификационные номера функциям, это страница, на которой он должен работать:

http://mtpassemblies.com/cs-cart/index.php?dispatch=products.view&product_id=29821

Поле номера детали должно быть заполнено, так как пользователь делает выбор между вариантами, это не происходит в реальной версии, и я не получаю никаких сообщений об ошибках. Так как я не получаю сообщений об ошибках, я не уверен, с чего мне начать искать причину проблемы.

В дополнение к моему первоначальному сообщению кажется, что CS Cart построен на платформе Smarty, я не уверен, имеет ли это отношение к проблеме?

Вот jQuery с сайта:

<script type="text/javascript">// <![CDATA[
$(function() {
var sku1 = sku2 = sku3 = sku4 = sku5 = sku6 = length = '';
$("#opt_29821_746").change(function(){

    switch($(this).val()){
        case "3134":
             sku1 = 'TB';
        break;
        case "3135":
             sku1 = 'LT';
        break;
        case "3154":
            sku1 = 'LTR';
        break;
        case "3136":
             sku1 = 'BO';
        break;
        case "3138":
             sku1 = 'MC';
        break;
        case "3139":
             sku1 = 'NC';
        break;
        case "3183":
              sku1 = 'STA';
        break;
    }
    $('#option_29821_798').val(sku1+sku2+sku3+sku4+sku5+sku6+length);
});
$("#opt_29821_742").change(function(){
    switch($(this).val()){
        case "3111":
              sku2 = 'LC';
        break;
        case "3110":
             sku2 ='LCA';
        break;
        case "3112":
             sku2 ='E2000';
        break;
        case "3113":
             sku2 ='E2A';
        break;
        case "3114":
             sku2 ='FC';
        break;
        case "3115":
             sku2 ='FCA';
        break;
        case "3116":
             sku2 ='ST';
        break;
        case "3117":
             sku2 ='SC';
        break;
        case "3118":
             sku2 ='SCA';
        break;
    }
    $('#option_29821_798').val(sku1+sku2+sku3+sku4+sku5+sku6+length);
});
$("#opt_29821_744").change(function(){
    switch($(this).val()){
        case "3175":
              sku3 = '2';
        break;
        case "3121":
             sku3 ='4';
        break;
        case "3122":
             sku3 ='6';
        break;
        case "3123":
             sku3 ='8';
        break;
        case "3124":
             sku3 ='12';
        break;
        case "3125":
             sku3 ='16';
        break;
        case "3126":
             sku3 ='24';
        break;
        case "3176":
             sku3 ='48';
        break;
    }
    $('#option_29821_798').val(sku1+sku2+sku3+sku4+sku5+sku6+length);
});

$("#opt_29821_745").change(function(){
    switch($(this).val()){
        case "3127":
              sku4 = 'OS12';
        break;
        case "3182":
             sku4 ='G657A1';
        break;
        case "3128":
             sku4 ='OM1';
        break;
        case "3129":
             sku4 ='OM2';
        break;
        case "3130":
             sku4 ='OM3';
        break;
        case "3131":
             sku4 ='OM4';
        break;
    }
    $('#option_29821_798').val(sku1+sku2+sku3+sku4+sku5+sku6+length);
});

$("#opt_29821_748").change(function(){
    switch($(this).val()){
        case "3142":
              sku5 = 'LC';
        break;
        case "3143":
             sku5 ='LCA';
        break;
        case "3144":
             sku5 ='E2000';
        break;
        case "3145":
             sku5 ='E2A';
        break;
        case "3146":
             sku5 ='FC';
        break;
        case "3147":
             sku5 ='FCA';
        break;
        case "3148":
             sku5 ='ST';
        break;
        case "3149":
             sku5 ='SC';
        break;
        case "3150":
             sku5 ='SCA';
        break;
    }
    $('#option_29821_798').val(sku1+sku2+sku3+sku4+sku5+sku6+length);
});

$("#opt_29821_749").change(function(){
    switch($(this).val()){
        case "3151":
              sku5 = 'LZSH';
        break;
        case "3177":
             sku5 ='PE';
        break;
    }
    $('#option_29821_798').val(sku1+sku2+sku3+sku4+sku5+sku6+length);
});

$('#opt_29821_753').change(function(){
    length = $(this).val();
    $('#option_29821_798').val(sku1+sku2+sku3+sku4+sku5+sku6+length);
});
});
// ]]></script>

UPDATE

После дальнейшего изучения и общения с разными людьми может показаться, что проблема будет вызвана встроенным событием onchange, встроенным в CS Cart, конфликтующим с написанным мной jQuery.

Таким образом, вопрос, похоже, заключается в том, можно ли заставить код работать вместе с функциями, запускаемыми встроенным кодированием?

Ответы [ 4 ]

4 голосов
/ 26 марта 2012

Событие .change() запускается только для статического содержимого. В вашем случае вы должны использовать событие jQuery .on(), например:

 $("#opt_29821_745").on('change', function() {
 ....
1 голос
/ 26 марта 2012

Попробуйте добавить это перед вашим кодом JavaScript.

jQuery.noConflict();

Или оберните ваш код jquery следующим образом:

jQuery(document).ready(function($){
   // your code here
});

Или заменить все $ на jQuery

0 голосов
/ 04 апреля 2012

Я думаю, это потому, что вы устанавливаете события на <div/>, а не <select/>.

$("#opt_29821_746").live('change', function(){

должно быть

$("#option_29821_746").live('change', function(){

Кроме того, у вас есть проблема с тем, что ваш обратный вызов AJAX сбрасывает все поля, потому что он просто устанавливает HTML-код, возвращаемый после заполнения поля, поэтому даже если код работает, он будет сбрасываться каждый раз. Подумайте о возврате простого списка (JSON будет моим выбором) и настройке параметров на стороне клиента, а не на рендеринге на стороне сервера. В качестве альтернативы, если вы настаиваете на использовании AJAX как есть, рассмотрите возможность отложить запрос AJAX до тех пор, пока вы не заполните поле (сначала заполните поле, а затем запрос AJAX). Я предполагаю, что это встроенный onclick, который вызывает AJAX. Так как это уродливо, я не буду бояться сделать его уродливым - вы можете сохранить onclick в стороне как данные jQuery и поместить его в следующую строку:

$('select[onchange]').each(function(i, el) { 
    el=$(el); 
    el.data('onchange', el.attr('onchange'));   // save previous event code aside
    el.attr("onchange",null);  // delete previous event code
    el.change(function() { 
        // you can actually add more code here to invoke before regular 'onchange' event
        var target=$(this);
        if (target.data("onchange")) {
            (new Function(target.data("onchange"))).apply(this, arguments);  }
    });
});

Однако вам нужно будет делать это после каждого вызова AJAX, когда ваши элементы заменяются. Вы также можете использовать jQuery live() и здесь, но мне это неприятно писать.

Что касается первого пункта, я думаю, что использование именованных переменных избавило бы вас от проблем. Для краткости, вот как я рекомендую вам пойти:

(function() { 

    // this isn't really ids but css selector; but for lack of a better name
    var el_id_map = {
        sku1: "#option_29821_746",
        sku2: "#option_29821_754",
        length: "#option_29821_753"
    };
    var el_ids = []; var sku_id="#option_29821_798";
    var sku1_map = { "3134": "TB", "3135": "LT" },
        sku2_map = { "3111": "LC", "3110": "LCA" };

    // map ids to array
    for (var key in el_id_map) { 
        if (el_id_map.hasOwnProperty(key)) el_ids.push(el_id_map[key]); 
    }

    $(el_ids.join(",")).live("change", function(){

        $(sku_id).val([
            sku1_map[$(el_id_map["sku1"]).val()],
            sku2_map[$(el_id_map["sku2"]).val()],
            $(el_id_map["length"]).val()].join(""));
    });

})()

Вы можете поместить код в обработчик live() здесь, в первом коде, который я сделал, где я разместил комментарий add more code here и т. Д. Но помните, что вы должны убедиться, что код запускается после каждого AJAX-запроса на обновление события обработчики.

Опять же, я просто вернул бы JSON с сервера.

Редактировать , так как я уже приложил усилия, я решил сделать полный, рабочий пример. Должен работать как есть на вашей странице, но вам нужно отладить его:)

(function() {
    // you might want to generate the list using the same
    // server-side data that generates the elements
    var el_id_map = {
        sku1: "#option_29821_746",
        sku2: "#option_29821_754",
        // put rest of skus here
        length: "#option_29821_753"
    };
    var sku_id = "#option_29821_798";
    var sku1_map = { "3134": "TB", "3135": "LT" },
        sku2_map = { "3111": "LC", "3110": "LCA" };
    // put rest of skus here

    var el_ids = []; 
    for (var key in el_id_map) { 
        if (el_id_map.hasOwnProperty(key)) {
            el_ids.push(el_id_map[key]); 
        }
    }
    function change_handler() {
        $(sku_id).val([
            sku1_map[$(el_id_map["sku1"]).val()],
            sku2_map[$(el_id_map["sku2"]).val()],
            $(el_id_map["length"]).val()].join(""));
    }
    function hijack_changes(change_handler) {
        $(el_ids).each(function(i, el) { 
            el = $(el); 
            el.data('onchange', el.attr('onchange')); // save inline event
            el.attr("onchange", null); // remove inline event
            el.change(function() { 
                change_handler.apply(this, arguments);

                var target=$(this);  
                if (target.data("onchange")) {
                    var handler = new Function(target.data("onchange"));
                    handler.apply(this, arguments);  
                }
            }); 
        });
    }

    function hijack_ajax() {
        var old_fn_post_process_form_files = window.fn_post_process_form_files;
        window.fn_post_process_form_files = function() {
            hijack_changes(change_handler);
            old_fn_post_process_form_files.apply(this, arguments);
        }
    }
    hijack_ajax();
    hijack_changes(change_handler);

})();
0 голосов
/ 04 апреля 2012

У меня была похожая проблема - текстовое поле, которое было подключено к средству выбора даты в JavaScript.я хотел использовать событие onchange для сравнения даты, выбранной с датой в другом поле (это было что-то вроде даты начала / даты окончания, и я хотел убедиться, что дата начала была раньше даты окончания - переключая их, если нет)

Только стрелка не стреляет.Решение состоит в том, чтобы использовать события onchange и onproperty.

на имеющемся у меня элементе управления:

<input id='mytext' name='mytext' type='text' onchange='doSomething();' onpropertychange='isDoSomething(event);' />

my isDoSomething выглядит следующим образом:

function isDoSomething(eventobj) {
if ("propertyName" in eventobj) { // Older browsers might not have this property
    if (eventobj.propertyName == 'value') // Check if the property that was changed was the value
        dosSomething();
}
else // on older browsers can't  check what property was changed so just do your thing
    doSomething();
}

Эточто сработало для меня - надеюсь, это поможет

на вашем примере: не только установить функцию .change, но и .propertychange

...