Javascript / jQuery: ошибка SCRIPT438 с IE7 / 8, какие-либо советы по отладке? - PullRequest
4 голосов
/ 30 июня 2011

У меня есть JavaScript, который отлично работает в Chrome, FF2 / 3 и IE9

158: drop_area = $('#drop_area');
159: element = ui.helper;

, однако я получаю следующую ошибку в IE7 и IE8:

SCRIPT438: Object doesn't support this property or method 
dragdrop.js, line 158 character 2

Мои знанияФункции отладки в IE7 довольно ограничены, но не похоже, что я действительно могу осмотреть рассматриваемый объект из консоли.Кто-нибудь знает, что может происходить здесь или как я могу лучше отладить эту ошибку

РЕДАКТИРОВАТЬ: понял немного больше контекста может быть полезным

function on_element_drop(event, ui){
    drop_area = $('#drop_area');
    element = ui.helper;

on_element_drop является методом обратного вызова дляСобытие отбрасывания пользовательского интерфейса jQuery

/*
 * dragdrop.js
 * Author: Casey Flynn
 * June 10, 2011
 * Global variables available to all functions
 */

//Keeps track of elements present in droppable and corresponding offsets/positions
var base_url = 'http://www.bla/';
var global_positions = new Array();
var current_item_group = 0;
var loaded = new Array();
var preloading = true;
var items = new Array(
    new Array(
        new Array(0, '2-Dollar'), 
        new Array(1, 'Cards'), 
        new Array(2, 'Cheese'),
        new Array(3, 'Coupons'),
        new Array(4, 'DogTags')),
    new Array(
        new Array(5, 'Doodle'), 
        new Array(6, 'Dreamcatcher'), 
        new Array(7, 'Fish'),
        new Array(8, 'Fortune'),
        new Array(9, 'Groucho')),
    new Array(
        new Array(10, 'HandTurkey'), 
        new Array(11, 'Key'), 
        new Array(12, 'Lolipop'),
        new Array(13, 'LotteryTicket'),
        new Array(14, 'Map')),
    new Array(
        new Array(15, 'Napkin'), 
        new Array(16, 'Notepad'), 
        new Array(17, 'OldPhoto'),
        new Array(18, 'Oragami'),
        new Array(19, 'Photo_Baby')),
    new Array(
        new Array(20, 'Photo_DJ'), 
        new Array(21, 'Photo_Dogs'), 
        new Array(22, 'Photo_Moustache'),
        new Array(23, 'Pick'),
        new Array(24, 'RabitsFoot')),
    new Array(
        new Array(25, 'Recipe'), 
        new Array(26, 'Reminder'), 
        new Array(27, 'Ribbon'),
        new Array(28, 'SheetMusic'),
        new Array(29, 'Smiley')),
    new Array(
        new Array(30, 'Spork'),
        new Array(31, 'Tape'),
        new Array(32, 'Ticket'),
        new Array(33, 'USB'),
        new Array(34, 'Viewmaster')
    )
);

/*
 * jQuery 'ready' handler, executes after DOM is ready and 
 * sets draggable/droppable properties of associated elements
 */
$(function(){   
    for(var i = 0; i < items.length; i++)
        loaded[i] = false;
    load_elements(0);

    $('#drop_area').droppable({
        //accept: '.draggable',
        //hoverClass: 'vel_content_active',        
        drop: on_element_drop
    });

    $('#countdown').html((10 - global_positions.length)+'');

});

// preloads an array of images
function preload(arrayOfImages) {
    $(arrayOfImages).each(function(){
        console.log('Preloading ' + this);
        $('<img/>')[0].src = this;
        // Alternatively you could use:
        // (new Image()).src = this;
    });
}


/*
 * Loads the first set of elements from 'items'
 */
function load_elements(arg0){
    set = items[arg0];
    box_handle = $('.bottom_content');
    elements = '';

    //construct html for elements to be added
    for(i=0; i<set.length; i++){
        elements += '<div class="draggable"><img alt="' + set[i][0] + '" src="' + base_url + 'application/assets/images/items/' + set[i][1] + '.png" /></div>';
    }

    //clear whatever was in there
    box_handle.empty();

    // element parent container
    box_handle.html(elements);

    //assign draggable status
    $('.draggable').draggable({
        revert: true,
        revertDuration: 0,
        helper: 'clone'
    });
    loaded[arg0] = true;
    if(preloading){
        var prev = next_elements(-1);
        var next = next_elements(1);
        if(!loaded[prev]){
            preload(items[prev])
            loaded[prev] = true;
        }
        if(!loaded[next]){
            preload(items[next])
            loaded[prev] = true;
        }
    }

}

function next_elements(arg0){
    if((current_item_group + arg0) == -1){
        return 6;
    }else{
        return ((current_item_group + arg0) % 7);
    }
}
/*
 * Cycles through element groups presented in .bottom_content
-1 to the left 1 to the right
 */
function cycle_elements(arg0){

    if((current_item_group + arg0) == -1){
        current_item_group = 6;
    }else{
        current_item_group = ((current_item_group + arg0) % 7);
    }

    load_elements(current_item_group);
}

/*
 * Callback function on drop event for droppable
 * Determines position of dropped element in droppable
 */
function on_element_drop(event, ui){
    drop_area = $('#drop_area');
    element = ui.helper;

    //Find relative x/y position of element inside drop_area
    var x = Math.floor((element.offset().left - drop_area.offset().left) / drop_area.width() * 100);
    var y = Math.floor((element.offset().top - drop_area.offset().top) / drop_area.height() * 100); 

    //console.log(ui); return;

    //console.log(ui.draggable.context.className.indexOf('draggable_dropped'));

    if(ui.draggable.context.className.indexOf('draggable_dropped') == -1){
        if(global_positions.length >= 10)
            return;

        //record element position and id
        row = new Array(parseInt($(ui.draggable).find("img").attr('alt')),
                        x,
                        y);

        //Add copy of item to drop_area at same x/y position where it was dropped
        add_element_copy_to_div(row);

        add_element_copy_to_global_positions(row);

    }else{
        //Item has already been dropped and is being adjusted, update global_positions
        //update global_positions
        id = ui.draggable.context.id;
        update_global_positions(id, x, y);
    }
    //$('#countdown').html((10 - global_positions.length)+'');
    console.log(global_positions);
}

/*
 * Finds element in global_positions and updates x & y values
 */
function update_global_positions(id, newX, newY){

    image_id = global_positions[id][0];

    global_positions[id] = new Array(image_id, newX, newY);

    /*
    var old_array = global_positions[find_index(global_positions, index)];
    var new_array = new Array(old_array[0], newX, newY);

    //.splice(i,1,pos) -- remove 1 element at index i and replace with pos
    global_positions.splice(index,1,new_array);
    */
}

/*
 * Helper function, determines if element is already present in 'global_positions'
 * Replaces if present, adds otherwise
 */
function add_element_copy_to_global_positions(pos){

    global_positions.push(pos);

    /*
    var found = false;

    for(i=0;i<global_positions.length;i++){
        if(global_positions[i][0] == pos[0]){
            //.splice(i,1,pos) -- remove 1 element at index i and replace with pos
            global_positions.splice(i,1,pos);
            found = true;
        }
    }

    if(!found)
        global_positions.push(pos);
    */
}

/*
 * Helper function, adds a copy of the draggable that was dropped into the droppable
 * for user visualization 
 */
function add_element_copy_to_div(pos){
    drop_area = $('#drop_area');
    id = global_positions.length;

    console.log('id: ' + id);

    //Convert % x&y offsets into absolute pixel offsets based on div size
    x = Math.floor(drop_area.width() * (pos[1] / 100));
    y = Math.floor(drop_area.height() * (pos[2] / 100));

    /*------- Find filename of image that has been dropped ------*/
    index = find_index(items[current_item_group], pos[0]);
    filename = items[current_item_group][index][1];

    drop_area.append('<div style="position:absolute;" class="draggable_dropped" id="' +  id  + '"><img src="' + base_url + 'application/assets/images/items/' + filename  + '.png" /></div>');
    $('#'+id).css('left', x);
    $('#'+id).css('top', y);

    //Set the newly dropped element to draggable so it can be repositioned
    $('#'+id).draggable({
        stop:function(event, ui){
            if(!is_valid_position(ui)) //invalid drop
                delete_item(ui);
        }
    });
}

/*
 * deletes element from global_positions and #drop_area when user drops item outside #drop_area
 *  also adjusts id attributes of all items
 */
function delete_item(ui){
    id = ui.helper.context.id;
    $('#'+id).remove();

    global_positions.splice(id, 1);

    $('#drop_area div').each(function(index){
        if(parseInt($(this).attr('id')) > parseInt(id))
            $(this).attr('id', parseInt($(this).attr('id')) - 1);
    });

    console.log(global_positions);
}

/*
 * helper for add_element_copy_to_div
 */
function is_valid_position(ui){
    drop_area = $('#drop_area');
    element = ui.helper;

    //Find relative x/y position of element inside drop_area
    var x = Math.floor((element.offset().left - drop_area.offset().left) / drop_area.width() * 100);
    var y = Math.floor((element.offset().top - drop_area.offset().top) / drop_area.height() * 100);

    if( (x < -5)  || 
        (x > 105) ||
        (y < -5)  ||
        (y > 105))
        return false;
    return true;
}

/*
 * helper for add_element_copy_to_div
 */
function find_index(items, search_index){
    for(i=0; i < items.length; i++){
        if(items[i][0] == search_index)
            return i;
    }
}

/*
 * Convert global_position array to JSON and submit to server via ajax along with csrf_token
 */
function update_layout(){
    $.ajax({
        url: '/projects/velcro/index.php/welcome/update_layout',
        type: 'post',
        data: {'layout_json' : $.toJSON(global_positions), 'ci_csrf_token' : $('input[name=ci_csrf_token]').val()},
        success: function(data, textStatus, jqXHR){
            //Redirect user to next page here...
            if(data == '1'){
                //alert('Layout successfully saved');
            }else{
                //alert('Layout save failed');
            }
            location.href = 'http://www.messageamplify.com/projects/velcro/index.php/welcome/create2';
        },
        error: function(jqXHR, textStatus, errorThrown){
            console.log('error: '+jqXHR);
            console.log(textStatus);
            console.log(errorThrown);
        }
    });
}

//End file 'dragdrop.js'

Ответы [ 2 ]

6 голосов
/ 30 июня 2011
drop_area = $('#drop_area');

Эта строка всегда выдает ошибку в IE.Это связано с тем, что в IE каждый элемент с идентификатором будет доступен через глобальный объект window, в данном случае window.drop_area.Но тот факт, что window является глобальным объектом, делает возможным доступ к объекту без глобального, в данном случае просто drop_area.

Таким образом, предложение drop_area = $('#drop_area'); не пытается присвоить объектк переменной, но пытается перезаписать элемент ссылку на другой объект.Это ошибка, которую вы видите как исключение во время выполнения.

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

  1. использовать оператор var, чтобы ограничить переменную внутри функции, содержащей код, и скрыть доступ к window.drop_area из глобального типа, например var drop_area = $('#drop_area'); или
  2. используйте другое имя переменной, например var dropArea = $('#drop_area');

И, как хороший совет, всегда указывайте область видимости переменных, которые вы используете с оператором var.

0 голосов
/ 30 июня 2011

IE8 имеет встроенный отладчик.Нажмите F12, перейдите на вкладку «Сценарий», нажмите «Начать отладку» и выполните отладку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...