最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavascriptjQuery : SCRIPT438 error with IE78, any debugging tips? - Stack Overflow

programmeradmin5浏览0评论

I have a javascript which works perfectly in chrome, FF2/3, and IE9

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

however I get the following error in IE7 amd IE8:

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

My knowledge of IE7's debugging features is pretty limited but it doesn't look like I can really inspect the object in question from the console. Does anyone know what might be going on here or how I can better debug this error

EDIT: Realized a little bit more context might be helpful

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

on_element_drop is a callback method for a jQuery UI droppable 'drop' event

/*
 * 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 = '/';
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/wele/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 = '.php/wele/create2';
        },
        error: function(jqXHR, textStatus, errorThrown){
            console.log('error: '+jqXHR);
            console.log(textStatus);
            console.log(errorThrown);
        }
    });
}

//End file 'dragdrop.js'

I have a javascript which works perfectly in chrome, FF2/3, and IE9

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

however I get the following error in IE7 amd IE8:

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

My knowledge of IE7's debugging features is pretty limited but it doesn't look like I can really inspect the object in question from the console. Does anyone know what might be going on here or how I can better debug this error

EDIT: Realized a little bit more context might be helpful

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

on_element_drop is a callback method for a jQuery UI droppable 'drop' event

/*
 * 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/wele/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./projects/velcro/index.php/wele/create2';
        },
        error: function(jqXHR, textStatus, errorThrown){
            console.log('error: '+jqXHR);
            console.log(textStatus);
            console.log(errorThrown);
        }
    });
}

//End file 'dragdrop.js'
Share Improve this question edited Jul 10, 2012 at 14:01 GG. 21.9k14 gold badges92 silver badges133 bronze badges asked Jun 29, 2011 at 21:49 Casey FlynnCasey Flynn 14k26 gold badges108 silver badges196 bronze badges 9
  • Sometimes IE errors are useless. can you post the code previous to this (please omit those line numbers...) – Naftali Commented Jun 29, 2011 at 21:51
  • Did you try Development Tools for IE? – Ivan Nevostruev Commented Jun 29, 2011 at 21:52
  • @Ivan Nevostruev, yes I have downloaded the IE Development Toolbar, I'm using the console within that add-on. I have to say, it seems like a much more primitive console than what I get with Firebug in Firefox or Chrome's debugging/development features – Casey Flynn Commented Jun 29, 2011 at 21:55
  • @Casey Where are drop_area and element declared? – Šime Vidas Commented Jun 29, 2011 at 22:03
  • 1 @Casey If it's a lot of code, consider Pastebin. – Šime Vidas Commented Jun 29, 2011 at 22:11
 |  Show 4 more ments

2 Answers 2

Reset to default 6
drop_area = $('#drop_area');

This line will always throw a error in IE. That's because in IE every element with id will be accessible through the global window object, in this case, window.drop_area. But the fact that window is a global object makes possible to access the object without the global, in this case, just drop_area.

So, the sentence drop_area = $('#drop_area'); is not trying to assign a object to a variable, but is trying to overwrite a element reference with another object. This is the error you are seeing as a runtime exception.

To bypass this exception, you need to assign the jQuery object to a variable. To do this, you have two choices:

  1. use a var statement to scope the variable inside the function that contains the code and hide the access to window.drop_area from the global, like var drop_area = $('#drop_area');, or
  2. use another variable name, like var dropArea = $('#drop_area');

And, as a good advice, always give a scope to the variables you are using with var statement.

IE8 has a built in debugger. Press F12, click the Script tab, click Start Debugging, and debug away.

发布评论

评论列表(0)

  1. 暂无评论