• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Tabellen Kopfzeile stehen lassen beim scrollen

Nachdem ich dieses richtig geile Script nun über ein Jahr in Betrieb habe muss ich sagen: einfach endgeil das Teil!

Eine kleine Frage ist allerdings noch aufgetaucht: Wenn man mit STRG F im aktuellen Bild etwas sucht finden sowohl IE als auch FF mehr Suchergebnisse als man sieht. Beim IE ist es exakt immer die doppelte Menge. Und wenn dann im IE durch die Suchergebnisse springt fängt der IE nach dem letzten sichtbaren Ergebnis an, die ganze Kopfzeile bis zur Unkenntlichkeit zu zermatschen.

Wenn ich das richtig gesehen habe clont das Script die Tabelle. Hängt das damit zusammen? Kann man da was machen?
Vielleicht hilft es: IE < 11, FF < 10, Chrome < 34 brauchen nicht unterstützt zu werden.

Hier die aktuelle Version die im Einsatz ist:
HTML:
function fixedTableHeader(tableID, resizeID) {
	var patch = (new Date()).getTime(),
		fixedHeader = false,
		scrollTimeout = false,
		// Get the original table and sections
		jqTable = jQuery('#' + tableID),
		jqCaption = jqTable.children('caption'),
		jqHead = jqTable.children('thead'),
		// Placeholders
		jqTempClone,
		jqTableTemp,
		jqTableClone,
		jqHeadClone,
		jqTableWrapper,
		jqTableCloneWrapper,
		jqTableOriginalMargin,
		// Calculations
		startPosLeft,
		startPosTop,
		endPosTop,
		tableHeightFix,
		jqTableCloneWrapperHeight,
		jqTableCloneScrollEndHeight,
		jqTableWrapperCSS = {},
		jqTableCloneWrapperCSS = {},
		captionHeight = jqCaption.length > 0 ? jqCaption.outerHeight() : 0,
		waitHeaderDisappear = false;

	function validate_jqTableWrapperCSS() {
		// Validate css properties of jqTableWrapper
//			jqTableWrapperCSS.border = '1px solid red';
		jqTableWrapperCSS.width = jqTable.outerWidth();
		jqTableWrapperCSS.height = jqTable.outerHeight() + tableHeightFix;
//			jqTableWrapperCSS.marginTop = jqTableOriginalMargin.marginTop;
//			jqTableWrapperCSS.marginRight = jqTableOriginalMargin.marginRight;
//			jqTableWrapperCSS.marginBottom = jqTableOriginalMargin.marginBottom;
//			jqTableWrapperCSS.marginLeft = jqTableOriginalMargin.marginLeft;
		jqTableWrapperCSS.overflow = 'hidden';
		switch (jqTable.css('position')) {
		case 'fixed':
			return;
		case 'static':
			jqTableWrapperCSS.position = 'relative';
			break;
		case 'relative':
			jqTableWrapperCSS.position = 'relative';
			jqTableWrapperCSS.left = jqTable.css('left');
			jqTableWrapperCSS.top = jqTable.css('top');
			jqTable.css('left', 0);
			jqTable.css('top', 0);
			break;
		case 'absolute':
			jqTableWrapperCSS.position = 'absolute';
			jqTableWrapperCSS.left = jqTable.css('left');
			jqTableWrapperCSS.top = jqTable.css('top');
			jqTable.css('left', 0);
			jqTable.css('top', 0);
			break;
		}
		jqTableWrapper.css(jqTableWrapperCSS);
	}

	function validate_jqTableCloneWrapperCSS() {
		// Validate css properties of jqTableCloneWrapper
		jqTableCloneWrapperCSS.width = '100%';
		jqTableCloneWrapperCSS.height = jqTableCloneWrapperHeight;
		jqTableCloneWrapperCSS.overflow = 'hidden';
		jqTableCloneWrapperCSS.position = jqTableWrapperCSS.position === 'relative' ? 'absolute' : 'relative';
		jqTableCloneWrapperCSS.left = 0;
		jqTableCloneWrapperCSS.top = captionHeight;
		jqTableCloneWrapper.css(jqTableCloneWrapperCSS);
	}

	function set_jqTableCloneWrapperHeight_jqTableCloneScrollEndHeight() {
		// Get needed height to show only until thead bottom
		var heightFix;

		jqTempClone = jqTable.clone();
		jqTempClone.children('tbody').children('tr:not(:last)').remove();
		jqTableWrapper.after(jqTempClone);
		heightFix = jqTempClone.outerHeight();
		jqTempClone.children('caption').remove();
		jqTableCloneScrollEndHeight = jqTempClone.outerHeight();
		tableHeightFix = jqTableCloneScrollEndHeight !== heightFix ? 0 : captionHeight;
		jqTempClone.children('tfoot').remove();
		jqTempClone.children('tbody').remove();
		jqTempClone.css('borderBottom', 0);
		jqTableCloneWrapperHeight = jqTempClone.outerHeight();
		jqTableCloneScrollEndHeight += captionHeight;
		jqTempClone.remove();
		waitHeaderDisappear =  waitHeaderDisappear ? jqTableCloneWrapperHeight : 0;
	}

	// Set values for scrolling
	function set_scrollingValues() {
		startPosLeft = jqTableWrapper.offset().left || jqTableWrapperCSS.left;
		startPosTop = jqTableWrapper.offset().top + captionHeight + waitHeaderDisappear || jqTableWrapperCSS.top + captionHeight + waitHeaderDisappear;
		endPosTop = startPosTop + jqTableWrapper.height() - jqTableCloneScrollEndHeight - waitHeaderDisappear;
	}

	// Clone table
	function cloneTable() {
		// Clone original table and original thead						################## CLONE
		jqTableClone = jqTable.clone();
		jqHeadClone = jqHead.clone();

		// Prevent double id and remove caption if one exists			################# SYSTEM
		jqTableClone[0].id = 'jqTableClone' + patch;
		jqTableClone.children('caption').remove();

		// Insert jqTableClone into jqTableCloneWrapper					################### DATA
		jqTableCloneWrapper.append(jqTableClone);
	}

	// Validate visual properties
	function validate_visualProperties() {
		// Set needed height to show only until thead bottom			################# DESIGN
		set_jqTableCloneWrapperHeight_jqTableCloneScrollEndHeight();

		// Validate css properties of jqTableWrapper					################# DESIGN
		validate_jqTableWrapperCSS();

		// Validate css properties of jqTableCloneWrapper				################# DESIGN
		validate_jqTableCloneWrapperCSS();
	}

	// Prevent double id's and name's in the cloned table
	function preventDoubleId() {
		var jqThead = jqTable.children('thead'),
			jqCaption = jqTableClone.children('caption'),
			jqTfoot = jqTableClone.children('tfoot'),
			jqTbody = jqTableClone.children('tbody');

		// table head
		jqThead.find('[id]').each(function () {
			this.id += patch;
		});
		jqThead.find('[name]').each(function () {
			this.name += patch;
		});
		// table caption
		jqCaption.find('[id]').each(function () {
			this.id += patch;
		});
		jqCaption.find('[name]').each(function () {
			this.name += patch;
		});
		// table footer
		jqTfoot.find('[id]').each(function () {
			this.id += patch;
		});
		jqTfoot.find('[name]').each(function () {
			this.name += patch;
		});
		// table body
		jqTbody.find('[id]').each(function () {
			this.id += patch;
		});
		jqTbody.find('[name]').each(function () {
			this.name += patch;
		});
	}

	// Store the original margin of the original table and set to zero
	jqTableOriginalMargin = {
		marginTop: jqTable.css('marginTop'),
		marginRight: jqTable.css('marginRight'),
		marginBottom: jqTable.css('marginBottom'),
		marginLeft: jqTable.css('marginLeft')
	};
	jqTable.css('margin', 0);

	// Wrap the original table
	jqTable.wrap('<div id="jqTableWrapper' + patch + '" />');
	jqTableWrapper = jQuery('#jqTableWrapper' + patch);

	// Append jqTableCloneWrapper after original table
	jqTable.after('<div id="jqTableCloneWrapper' + patch + '" />');
	jqTableCloneWrapper = jQuery('#jqTableCloneWrapper' + patch);

	// Create temporary table object
	jqTableTemp = jQuery('<table/>', {id: 'tempTable' + patch});
	jqTableWrapper.after(jqTableTemp);

	// Clone table
	cloneTable();

	// Exchange the headers for event handling							################## EVENT
	jqTableClone.children('thead').remove();
	jqTableClone.prepend(jqHead);
	jqTable.prepend(jqHeadClone);

	// Validate visual properties
	validate_visualProperties();

	// Set values for scrolling											####### SCROLLING VALUES
	set_scrollingValues();

	// Prevent double id's and name's in the cloned table
	preventDoubleId();

	// Header move function
	function headerMove() {
		var animatePosition,
			scrollPosTop = jQuery(window).scrollTop();

		// Set values for scrolling										####### SCROLLING VALUES
		set_scrollingValues();

		if (scrollTimeout) {
			clearTimeout(scrollTimeout);
			scrollTimeout = false;
		}

		animatePosition = function () {
			scrollTimeout = false;
			jqTableCloneWrapper.stop().animate({
				top: jQuery(window).scrollTop() + captionHeight + waitHeaderDisappear - startPosTop
			}, 400);
		};

		if (scrollPosTop > startPosTop) {
			if (!fixedHeader) {
				fixedHeader = true;
			}
			if (scrollPosTop < endPosTop) {
				scrollTimeout = setTimeout(animatePosition, 50);
			} else {
				jqTableCloneWrapper.stop().css('top', endPosTop + captionHeight + waitHeaderDisappear - startPosTop);
			}
		} else {
			scrollTimeout = false;
			jqTableCloneWrapper.stop().css('top', captionHeight);
			fixedHeader = false;
		}
	}

	// Let it scroll...
	jQuery(window).scroll(headerMove);

	// Bind resize event to the browser window
	window.onresize = document.onresize = document.documentElement.onresize = headerMove;
	if (document.getElementById(resizeID)) {
		document.getElementById(resizeID).onresize = headerMove;
	}

	// Bind fixedTableHeaderUpdate event to the original table
	jqTable.on('fixedTableHeaderUpdate', function () {
		var theadEvents = jqTable.children('thead').find('th').data('events'),
			theadCloneEvents = jqTableClone.children('thead').find('th').data('events');
		var jqThead = jqTable.children('thead');

		// Restore modified id's and name's in the cloned table head to its original
		jqThead.find('[id]').each(function () {
			this.id = this.id.replace(patch, '');
		});
		jqThead.find('[name]').each(function () {
			this.name = this.name.replace(patch, '')
		});

		// Check caption height
		captionHeight = jqCaption.length > 0 ? jqCaption.outerHeight() : 0;

		if (typeof theadEvents === 'undefined' && typeof theadCloneEvents !== 'undefined') {
			// Store original thead with registered events
			jqTableTemp.prepend(jqHead);
		}

		// Remove jqTableClone from jqTableCloneWrapper					################### DATA
		jqTableClone.remove();

		// Clone table
		cloneTable();

		if (typeof theadEvents === 'undefined' && typeof theadCloneEvents !== 'undefined') {
			// Exchange the headers for event handling					################## EVENT
			jqTableClone.children('thead').remove();
			jqTableClone.prepend(jqHead);
		} else if (typeof theadEvents !== 'undefined') {
			// Update jqHead and jqHeadClone
			jqHead = jqTable.children('thead');
			jqHeadClone = jqHead.clone();

			// Exchange the headers for event handling					################## EVENT
			jqTableClone.children('thead').remove();
			jqTableClone.prepend(jqHead);
			jqTable.prepend(jqHeadClone);
		}

		// Validate visual properties
		validate_visualProperties();

		// Set values for scrolling										####### SCROLLING VALUES
		set_scrollingValues();

		// Prevent double id's and name's in the cloned table
		preventDoubleId();

		if (fixedHeader) {
			jqTableCloneWrapper.css({
				top: jQuery(window).scrollTop() + captionHeight - startPosTop
			});
		}
	});
}
 
Zuletzt bearbeitet:
Der ganze Ansatz basiert doch darauf, dass die komplette Tabelle geclont wird und die Tabelle nur durch overflow: hidden "versteckt" wird. Ich wüsste nicht, wie man da etwas machen könnte.

Bei meinem Ansatz ist die Tabelle nicht doppelt im DOM - dafür ist er noch nicht wirklich ausgereift... da ich aber selber sowas gerade brauche, werd' ich da mal etwas dran rumschrauben.
 
mini und Korbinian, ist einer von euch zufällig schon dazu kommen, sich das hier anzuschauen? Eilt nicht, will nicht drängeln. Wollte nur mal fragen.
 
Hab mir das nochmal angeschaut. Sofern man alles unter IE9 ignorieren kann hätte ich auch schon eine Idee. Muss aber noch etwas intensiver testen. Bei der modernen Variante wäre zumindest aber die Kopfzeile doppelt.
 
Sofern man alles unter IE9 ignorieren kann
Soweit es mein Einsatzgebiet betrifft ist das völlig in Ordnung. Bei Korbinian weiß ich nicht. Und den 9er auch nur deshalb, weil er der letzte für XP ist.

Bei der modernen Variante wäre zumindest aber die Kopfzeile doppelt.
Das wäre auf jeden Fall schon mal erheblich besser als vorher.

Jetzt bin ich mir nur nicht sicher, wie wir mit den Versionen umgehen. Wenn ich das noch alles richtig im Kopf habe, hatte seinerzeit Korbinian das Script fertig gemacht, weil du dann keine Zeit mehr hattest. Die aktuelle ist in Beitrag 143 zu sehen. Es wäre gut, wenn du die als Ausgangsbasis nehmen würdest, wir hatten nämlich noch einiges daran rum geschraubt seinerzeit.
 
Und den 9er auch nur deshalb, weil er der letzte für XP ist.
Da bist du aber auf dem falschen Dampfer. Für Windows XP gibt es nur die Trident Layout Engine bis Version 4.0 was dem IE 8 entspricht, siehe Wikipedia...Internet Explorer versions


Jetzt bin ich mir nur nicht sicher, wie wir mit den Versionen umgehen. Wenn ich das noch alles richtig im Kopf habe, hatte seinerzeit Korbinian das Script fertig gemacht, weil du dann keine Zeit mehr hattest. Die aktuelle ist in Beitrag 143 zu sehen. Es wäre gut, wenn du die als Ausgangsbasis nehmen würdest, wir hatten nämlich noch einiges daran rum geschraubt seinerzeit.
Werde ich mir nochmal anschauen, aber verwechselst du das nicht evtl. mit dem Timepicker (Lotus style)?
 
Für Windows XP gibt es nur die Trident Layout Engine bis Version 4.0 was dem IE 8 entspricht
Ach Mist, ich hab mich vertan. Meinte den 8er. Aber auch den brauche ich mittlerweile nicht mehr. Hab mal in die Browserstatistik geschaut, der IE kommt - wenn überhaupt - nur ab 10 vor.

Werde ich mir nochmal anschauen, aber verwechselst du das nicht evtl. mit dem Timepicker (Lotus style)?
Ich hatte noch Mailverkehr mit Korbinian zum Stichwort fixedTableHeader gefunden bevor ich die Mails wegen Speicherplatzüberschreitung löschen musste. Aber ich kann dir nicht mehr genau sagen, was da war.
Korbinian, weißt du das noch?
Sonst ist es ja nicht schlimm, den aktuellen Stand hab ich ja hier gepostet.
 
Habe es nicht vergessen und schon teilweise umgeschrieben, aber wegen Zeitmangel noch nicht soweit gekommen wie ich gerne wollte. Melde mich aber wenn die erste Testversion steht.
 
Zurück
Oben