Ответ 1
Спасибо за все ответы и комментарии. Наконец, я смог выяснить, по крайней мере, частичное решение, которое работает для меня.
Прежде всего, я смог перестроить свой HTML, так что теперь элементы "non note" в левом td завернуты в один div
, который теперь является самым первым элементом в td. Итак, теперь между нотами нет ничего, может быть, что-то перед ними.
Идея моего решения заключается не в том, чтобы дать заметкам новую позицию, а для каждого из них установить новый margin-top
. Максимальное количество значений margin-top
, добавляемых в ячейку таблицы, вычисляется до (называемое "пространство роуминга" ), являющееся пространством ниже последней ноты в ячейке таблицы. Таким образом, расположение таблицы не разрушается.
function move_notes() {
$('tr').each(function (index, value) {
var current_tr = $(this);
var last_app_element_in_tr = $(this).find('span[class*="note"]').last();
if ($(last_app_element_in_tr).length) /* Only preceed if there is at least one note in the table row */ {
var tr_height = $(this).height();
var tr_offset = $(this).offset().top;
var bottom_of_tr = tr_offset + tr_height;
var bottom_of_last_app_el = $(last_app_element_in_tr).offset().top + $(last_app_element_in_tr).height();
var roaming_space = bottom_of_tr - bottom_of_last_app_el; // Calculate the amount of pixels which are "free": The space below the very last note element
$(this).find('span[class*="note"]').each(function (index, value) {
var my_id = $(this).attr('id');
var element_ref = $(current_tr).find("#" + my_id + "_anchor");
var pos_of_ref = $(element_ref).offset().top;
var new_margin_top;
/* Calculate the new margin top: The note should be at the same level as the reference element.
When loading, in most cases the notes are placed too high. So, the margin top of the note should equal
the amount of pixels which the note is "too high". So we subtract the height and the offset of the element
before the current note from the offset of the reference. */
var previous_note = $(this).prev();
// not just notes, but every element in the td in general
if (! $(previous_note).length) // If there is no previous_note, than take the table cell
{
closest_td = $(this).closest("td");
new_margin_top = pos_of_ref - $(closest_td).offset().top;
} else {
new_margin_top = pos_of_ref - $(previous_note).offset().top - $(previous_note).height();
}
var difference_to_previous = $(this).css('marginTop').replace(/[^-\d\.]/g, '') - new_margin_top; // Calculate the difference between the old and the new margin top
if (new_margin_top > 0 && Math.abs(difference_to_previous) > 2) // Only move, if the new margin is greater than zero (no negative margins!) if the difference is greater than 2px (thus preventing ugly "micro moving".
{
var new_roaming_space = roaming_space - difference_to_previous;
if (new_roaming_space > 0) /* if there is still room to move */ {
var margin_top_ready = new_margin_top + "px";
$(this).css('margin-top', margin_top_ready);
roaming_space = new_roaming_space;
} else /* If there is no more space to move: */ {
var margin_top_ready = roaming_space + "px"; // take the rest of the "roaming space" left as margin top
$(this).css('margin-top', margin_top_ready);
return false; // Stop the execution because there is nothing left to do.
}
}
});
}
});
}
window.onload = function () {
move_notes();
};
$(window).resize(function () {
move_notes();
});
Как вы заметили, одна из моих основных проблем все еще не решена: заметки только перемещаются вниз, никогда не поднимаются. Из-за различных проблем с моей реальной веб-страницей я еще не реализовал это. Тем не менее, алгоритм может быть чем-то вроде: если верхний верхний край больше высоты текущей ноты, а разница между выводом текущего якоря примечания и нижестоящим анкетом примечания меньше высоты текущей заметки, чем вычитаем высоту текущей ноты с нового поля.
Тем не менее остаются две проблемы:
- Если окно максимизируется или быстро изменяется с довольно тонкой ширины на большую ширину, настройка позиций нот не будет работать. Я не знаю, почему.
- Производительность может быть лучше. Как пользователь, вы можете видеть, как заметки спрыгивают. (Из-за странного и непредсказуемого поведения в Firefox мне пришлось переместить обработчик событий с
document.ready
наwindow.onload
)