When are DOM updates done children elements added in javascript
In javascript I create divs that are placed on the page. I get the top left width height for the last added element to place the new one. The information is saved to an xml file to place the divs when the page is reloaded. When I retrieve the placement for the last div, the information I get is the one for the div placed from the xml info. In other words, the divs created in javascript don't seem to be in the DOM yet. Is there a function that I must call for the DOM to be updated?
Here is the code where I retrieve the information for the last div on the page.
var last_top = $('.linkcard:last', $("#page")).position().top;
var last_left = $('.linkcard:last', $("#page")).position().left;
var last_height = $('.linkcard:last', $("#page")).height();
var last_width = $('.linkcard:last', $("#page")).width();
This code is called in the onClick event of a button. The first time it works and retrieves the information for the static divs (the ones retrieved from xml). The subsequent times, it doesn't retrieve the right information because it doesn't seem to know about the div added in javascript. I imagine that the code as written looks at a part of the DOM that doesn't know about the new div. Is that right? What should I do to get the right information?
EDIT
* Complete javascript function *
function create_linkcard() {
// Create LinkCard id
var created_id_string = $.ajax({
url: "create_id.php",
type: "GET",
data: { },
cache: false,
async: false,
success: function (response) {
if (response != '')
{
/* alert(response); */
}
}
}).responseText;
var card_id = "c" + String(created_id_string);
// Create Linkcard, add toolbar, resize #page
$("#page").append('<div id="'+card_id+'" class="linkcard_init ui-widget-content" style="z-index: 9999;"></div>');
$('#'+card_id).append('<p class="linkcard_header editableText">C'+created_id_string+'</p>');
// Make edit box for LinkCard title
$('#'+card_id).append('<form id="frm_name" name="frm_name" class="editableToolbar frm_add_linkcard"> <input type="text" placeholder="Type a name..." name="linkcard_name" class="txt_form"> <a href="#" title="Save" class="save btn_form" onClick="save_name(\''+card_id+'\', this.form); "></a> <a href="#" title="Cancel" class="cancel btn_form" onClick="delete_linkcard('+'\''+card_id+'\''+');"></a> </form>');
// Add toolbar
$('#'+card_id).append('<div class="toolbar"> <a href="#" title="Options" class="ico_tools"></a> <a href="#" title="Delete" class="ico_delete" onClick="delete_linkcard('+'\''+card_id+'\''+');"></a> </div>');
// Add drag and drop box
$('#'+card_id).append('<div class="link_drop_box"></div>');
// Add scrolling buttons
$('#'+card_id).append('<div class="scrolling_prev" title="Previous"></div>');
$('#'+card_id).append('<div class="scrolling_next" title="Next"></div>');
// Add search tool and add link tool
$('#'+card_id).append('<div class="tools" > <a href="#" title="Add开发者_开发问答 Link" class="ico_add" onClick="add_link('+'\''+card_id+'\''+');"></a> <a href="#" title="Search Links" class="ico_search" onClick="open_search('+'\''+card_id+'\''+');"></a> </div>');
// Add script for scrolling
$(document).ready(function($) {
$(".scrolling_prev", $('#'+card_id)).mousedown(function() {
startScrolling($(".link_drop_box", $('#'+card_id)), "-=50px");
}).mouseup(function() {
$(".link_drop_box", $('#'+card_id)).stop()
});
$(".scrolling_next", $('#'+card_id)).mousedown(function() {
startScrolling($(".link_drop_box", $('#'+card_id)), "+=50px");
}).mouseup(function() {
$(".link_drop_box", $('#'+card_id)).stop();
});
});
// Place new LinkCard
/* var last_top = parseInt($('.linkcard:last', $("#page")).position().top);
var last_left = parseInt($('.linkcard:last', $("#page")).position().left);
var last_otop = parseInt($('.linkcard:last', $("#page")).offset().top);
var last_oleft = parseInt($('.linkcard:last', $("#page")).offset().left);
var last_height = parseInt($('.linkcard:last', $("#page")).height());
var last_width = parseInt($('.linkcard:last', $("#page")).width()); */
var last_top = parseInt($("#page").children('.linkcard:last').position().top);
var last_left = parseInt($("#page").children('.linkcard:last').position().left);
var last_otop = parseInt($("#page").children('.linkcard:last').offset().top);
var last_oleft = parseInt($("#page").children('.linkcard:last').offset().left);
var last_height = parseInt($("#page").children('.linkcard:last').height());
var last_width = parseInt($("#page").children('.linkcard:last').width());
alert ('top '+last_top+' left '+last_left+' offset top '+last_otop+' offset left '+last_oleft);
var new_top = 0;
var new_left = 0;
/* if (last_left < 250) {
new_top = last_top - last_height - last_height;
new_left = last_left + last_width + 20;
}
else {
new_top = last_top - last_height + 20;
new_left = 0;
}*/
if (last_left < 250) {
new_top = last_top - last_height - last_height;
new_left = last_left + last_width + 20;
}
else {
new_top = last_top - last_height + 20;
new_left = 0;
}
// Define more LinkCard options
$('#'+card_id).css('width',350);
$('#'+card_id).css('height',250);
$('#'+card_id).css('top',new_top);
$('#'+card_id).css('left',new_left);
$('#'+card_id).resizable();
$('#'+card_id).draggable();
$('#'+card_id).draggable("option", "handle", '.linkcard_header');
$('#'+card_id+' p').editableText();
$('#'+card_id).draggable({ stop: function(event, ui) { update_linkcard_xml(card_id) } });
// Make droppable
$('div.link_drop_box', $('#'+card_id)).droppable({
drop: function( event, ui ) {
var $item = ui.draggable;
$item.fadeOut(function() {
$item.css( {"left":"", "top":"", "bottom":"", "right":"" }).fadeIn();
});
$item.appendTo( this );
/* update_links_xml("card_id"); */
},
out: function( event, ui ) {
/* update_links_xml("card_id"); */
},
accept: ".link",
});
// Get LinkCard info for XML
linkcard_name = $('#'+card_id).children('.linkcard_header').text();
linkcard_top = $('#'+card_id).position().top;
linkcard_left = $('#'+card_id).position().left;
linkcard_width = $('#'+card_id).width();
linkcard_height = $('#'+card_id).height();
// Scroll LinkCard into view
linkcard_offset = $('#'+card_id).offset().top+40;
var scroll_top = parseInt(linkcard_top);
alert (linkcard_offset);
$('#matting').scrollTop(linkcard_offset);
// Make ajax call to update XML
$.ajax({
url: "add_node.php",
type: "POST",
data: { nodeid: card_id, name: linkcard_name, top: linkcard_top, left: linkcard_left, width: linkcard_width, height: linkcard_height },
cache: false,
success: function (response) {
if (response != '')
{
/* alert(response); */
}
}
});
}
The DOM is updated after each of your calls to .append()
. I'm still not sure if I fully understand what you are trying to achieve, but here is what I noticed on your code:
When you assign to
last_*
variables, you are getting the information from the last<div>
with classlinkcard
. However, new divs created withcreate_linkcard()
do not have thelinkcard
class. Instead, they have classlinkcard_init
. So your next call tocreate_linkcard()
will never find the new div, because it doesn't have the class you're targeting.If you just change the class name
linkcard_init
tolinkcard
, your code will fail, because your logic appends the new div first, and only after that it looks for thelast_*
values. So, the last values will be assigned the top, left, width and height of the new div you just inserted, instead of the one before that.I noticed your code begins with a synchronous call to the server. That will probably freeze the UI for a while. Isn't that a problem?
精彩评论