Javascript / jQuery:IE7 / 8的SCRIPT438错误,有什么调试技巧吗?

时间:2011-06-29 21:49:57

标签: javascript jquery internet-explorer-7

我有一个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 UI droppable'drop'事件的回调方法

/*
 * 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 个答案:

答案 0 :(得分:6)

drop_area = $('#drop_area');

此行将 始终 在IE中引发错误。这是因为在IE中,每个具有id的元素都可以通过全局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');
  3. 而且,作为一个好建议,请始终使用var语句为您使用的变量提供范围。

答案 1 :(得分:0)

IE8内置调试器。按F12,单击“脚本”选项卡,单击“开始调试”,然后调试。