Warnung: file_put_contents(/home/www/web1/html/php_dev/test.txt) [function.file-put-contents]: failed to open stream: Permission denied in /home/www/web1/html/php_dev/sys/lib.activity.php (Zeile 58)
HTML-Code der aktuellen Auswahl [Archiv] - PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr
ebiz-webhosting
- Ad -
php-resource




Archiv verlassen und diese Seite im Standarddesign anzeigen :
HTML-Code der aktuellen Auswahl


 
squirrelcgn
23-07-2009, 16:39 
 
Hallo zusammen,

bin schon seit Tagen auf der Suche nach einem geeigneten Ansatzpunkt für ein (wahrscheinlich kleines) Problem - mittlerweile bin ich mir sicher, dass JavaScript die beste/einzige Sprache sein dürfte, mit der das Problem überhaupt lösbar ist.

PROBLEM
Man markiert (mit der Maus) auf einer im Browser angezeigten Webseite ein kleines Stück Text. Nun möchte ich erreichen, dass der gesamte "übergeordnete HTML-Tag" (inklusive parameter und content) extrahiert/gespeichert wird. Im folgenden ein einfaches Beispiel.

BEISPIEL

(1.) Text/Textteil auswählen
http://i25.tinypic.com/2hhiy50.gif

(2.) Button klicken oder evtl. via EventHandler Punkt (3.) anstoßen.


(3.) Es wird der "übergeordnete HTML-Tag" ermittelt (und gespeichert)
http://i29.tinypic.com/nqe0qw.gif


Es wäre super, wenn mir jemand hier (vielleicht sogar aus eigener Erfahrung) einen Tipp geben könnte, wie ich hier einsteigen/herangehen sollte.

Vielen Dank im Voraus und Grüße,
Christian

 
AmicaNoctis
23-07-2009, 17:07 
 
Hallo Christian,

das macht man mit sogenannten Ranges

im IE: TextRange Object (http://msdn.microsoft.com/en-us/library/ms535872%28VS.85%29.aspx)

im Firefox: https://developer.mozilla.org/en/DOM/Selection

das W3C sagt: Document Object Model Range (http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html)

Gruß,

Anja

 
squirrelcgn
23-07-2009, 17:15 
 
Vielen Dank, Anja! Dein Tipp ist Gold wert! Da werde ich mich jetzt mal intensiv reinlesen.

Grüße,
Christian

 
squirrelcgn
23-07-2009, 20:26 
 
Hallo zusammen,
hallo Anja,

bin jetzt schon recht weit gekommen, aber hänge an einer Stelle fest. Vielleicht könnt ihr mich kurz schubsen... ;-) Der folgende HTML-Code funktioniert in FF und Opera.

<html>

<head>

<script type="text/javascript">

function showSelection() {
// (*)
var selObj = window.getSelection();
alert(selObj);
//var selRange = selObj.getRangeAt(0);

// (**)
var anchorNode = selObj.anchorNode;
var parentNode = anchorNode.parentNode;
alert(parentNode);
}

</script>

</head>

<body>

<p>Hier steht Text. Und noch mehr Text. Und noch viel mehr Text...</p>

<input type="button" value="Start" onclick="showSelection()">

</body>

</html>

Ich würde ja gerne erreichen, dass beim zweiten alert (im Teil (**) im Code) nicht "object HTMLParagraphElement" ausgegeben wird, sondern eben der GESAMTE ParagraphElement ansich, also "<p>Hier steht Text. Und noch mehr Text. Und noch viel mehr Text...</p>". Leider klappt es auch bei Anwendung von "toString()" nicht.

Die von Anja genannte Site https://developer.mozilla.org/en/DOM/Selection ist sehr gut, aber ich finde dort leider nicht die von mir gesuchte property/method.

Bin für jeden Tipp sehr dankbar!

Viele Grüße!

 
Kropff
23-07-2009, 21:03 
 
Erstens. Benenne Variablen nie wie JavaScript-Eigenschaften/-Methoden! Ganz böse! Also lieber so:

var anch = selObj.anchorNode;
var par = anch.parentNode;
alert(par);

Und nun zu deiner Frage. Da gibt es zwei Möglichkeiten. Erstens

// Ungetestet
alert (par.innerHTML);
oder du gehst komplett über das DOM und schnipselst dir alles zusammen. Also mit firstChild und nodeValue/data. Eine Übersicht dazu findest du bei mir (http://www.peterkropff.de/site/javascript/dom_manipulation.htm)

Peter

 
squirrelcgn
23-07-2009, 21:21 
 
Wow!! Danke, Peter! Deine Website ist ja der Hammer, eine wahre Fundgrube!

Sehe ich es richtig, dass ich nicht drum herum komme, die Tags "beim Namen zu nennen"? Muss ich zwingend die Namen der Tags angeben, also z.B. getElementByTagName("p").firstChild.nodeValue? Kann ich das getElementByXY() vermeiden?

Zusammenfassend kann ich das Problem jetzt umformulieren:
Wie kann ich den gesamten umgebenen Tag (mit Tag-Zeichen (<, >), properties und content) einer Range ausgeben?

Danke und Grüße!

 
AmicaNoctis
23-07-2009, 21:59 
 
Wenn ein Element ein ID-Attribut hat, kannst du es auch mit
document.getElementById("deineID")
ansprechen.

Elemente in der Nähe eines auf die Art geholten erreichst du über


deinElement.parentNode
deinElement.previousSibling
deinElement.nextSibling
deinElement.firstChild
deinElement.lastChild
deinElement.childNodes[deinIndex]


Theoretisch kannst du damit von document ausgehend auch alle Knoten erreichen, das kann aber schnell unübersichtlich werden ;)

 
Kropff
23-07-2009, 22:12 
 
Sehe ich es richtig, dass ich nicht drum herum komme, die Tags "beim Namen zu nennen"? Muss ich zwingend die Namen der Tags angeben, also z.B. getElementByTagName("p").firstChild.nodeValue? Kann ich das getElementByXY() vermeiden?
Wie du es machst, ist deine Entscheidung. JavaScript läßt dir da leider/gottseidank viele Freiheiten. Mein Tipp. Verpass den wirklich wichtigen Elementen eine ID und arbeite mit document.getElementById.

Peter

 
squirrelcgn
23-07-2009, 22:42 
 
Danke Euch Peter und AmicaNoctis!

Ich MUSS es aber leider komplett ohne ID-Neuvergabe lösen! Das ist leider unumgänglich... :-( Ich muss quasi davon ausgehen, dass ich die Struktur des gesamten Dokumentes nicht kenne. Meine Idee ist ja: von der markierten Stelle "eine Ebene nach oben gehen" und schon hat man den gesamten "übergerodneten HTML-Tag". Aber ich glaube das ist gar nicht so einfach... (oder ich drücke mich die ganze Zeit unscharf aus).

Im Prinzip würde es doch auch reichen, wenn ich es hinbekommen würde die POSITION im HTML-Code (als Integer) zu ermitteln, an der die Range beginnt!

Habt ihr dazu vielleicht eine Idee?

Danke und Grüße!

 
AmicaNoctis
23-07-2009, 22:51 
 
So etwas wie eine implizite Integer-ID für alle Knoten gibt es nicht, es sei denn du baust selber eine traverse-Funktion, aber das widerspricht noch mehr der Grundlage, dass du das Dokument "nicht kennst".

"Eine Ebene nach oben gehen" ist ganz einfach:

aktuellerKnoten.parentNode

Damit bekommst du den Elternknoten. Wenn du das schon weißt, muss ich wirklich zugeben, dass du dich unscharf ausgedrückt hast ;)

Das innerHTML hast du schon probiert, ja?

 
squirrelcgn
23-07-2009, 23:05 
 
Okay, danke AmicaNoctis! Sowohl parentNode als auch innerHTML hatte ich bereits ausprobiert, leider ohne Erfolg.

Ich frage mal ganz direkt und herausfordernd: wie würdest du/würdet ihr denn das im Anfangspost geschilderte Problem lösen? Vielleicht gibt es ja jemanden, der das in 2 Minuten hinbekommt und sich etwas dazuverdienen möchte? ;-)

Danke und Grüße!!

 
AmicaNoctis
23-07-2009, 23:10 
 
Dafür wären mindestens noch zwei Sachen interessant:

1. Warum speicherst du den HTML-Code des übergeordneten Elements? Vielleicht hast du ja damit was vor, was sich besser lösen lässt, wenn du das Elementobjekt speicherst?

2. Was soll passieren, wenn man über Elementgrenzen hinweg selektiert hat? Theoretisch kann die Selektion einen Teilbaum enthalten und nicht nur einen Knoten oder Teil davon.

 
squirrelcgn
24-07-2009, 02:01 
 
Hallo zusammen,
hallo AmicaNoctis,

habe gerade versucht, Antworten auf AmicaNoctis' Fragen zu formulieren, da ist mir eingefallen, dass das Problem vllt. von einer ganz anderen Seite angegangen werden sollte...

Was ich "nachbauen" möchte ist im Prinzip EXAKT das gleiche, was passiert, wenn man in Firefox das Addon "Firebug" installiert und dort im Modus "Untersuchen" ("Inspector") mit der Maus über die aktive Website "fliegt": es werden (inder oberen Screenhälfte) alle Tags gehighlightet, die man mit der Maus berührt und (in der unteren Screenhälfte) die kompletten zugehörigen Tags angezeigt. (Firebug: https://addons.mozilla.org/de/firefox/addon/1843)

Im Prinzip möchte ich diese Funktion "nur" so erweitern, dass man, wenn man einen Tag/Text mit Firebug-Inspector gehighlightet hat, durch simples Klicken den Inhalt des Code-Inspectors (untere Hälte des Firebug-Screens) irgendwie abspeichern kann.

Kannst du / könnt ihr das nachvollziehen? Ich hoffe das ist nicht allzu verwirrend! ;-)

Da Firebug open source ist, habe ich mir mal den code des "Firebug Inspectors" (inspector.js) angeschaut: http://code.google.com/p/fbug/source/browse/branches/firebug1.5/content/firebug/inspector.js Allerdings ist das für mich derart komplex und unübersichtlich, dass ich den "missing link" für mein Puzzle leider dort nicht identifizieren kann.

Kann mir jemand dabei helfen?

Danke und Grüße!

 
AmicaNoctis
24-07-2009, 02:26 
 
also brauchst du den Umweg über die Selection/Ranges eigentlich gar nicht, wenn dir das Hovern schon reicht und du z. B. mit STRG+C das gewählte Element in die Zwischenablage bekommst?

Als Beispiel (so was ähnliches mit hovering, aber ohne Zwischenablage) hätte ich ein Bookmarklet für dich, was ich mal geschrieben hab, um Layer-Ads wegzumachen ("Schließen" bedeutet bei denen manchmal das Gegenteil) und um Seiten in eine Druckversion zu überführen (Bilder und Navigation entfernen).

Das Teil funktioniert so: du aktivierst das Bookmarklet (aka Favelet) und hoverst über die Seite. Das Element unter der Maus wird jeweils hervorgehoben. Wenn du es löschen willst, drückst du ENTF und hoverst weiter oder beendest das ganze mit ESC.

Hier der "Link" (ohne '):
'javascript:void((function(){var%20s=document.body.appendChild(document.createElement("script"));s.type="text/javascript";s.src="http://sedna-soft.de/js/favelet/remove-elements.js";})());'

ACHTUNG: irgendwie macht die Forensoftware bei "s.type" immer ein Leerzeichen rein, das muss natürlich weg! Ich bekomme es einfach nicht weg, obwohl es ja nie da war.

Hier der Quelltext: http://sedna-soft.de/js/favelet/remove-elements.js

Du musst dann nur noch document.onkeydown an deine Bedürfnisse anpassen. Wenn du dann wieder nicht weiterkommst, kannste dich ja immer nochmal melden...

Nur so nebenbei: statt Geld würde ich mich über eine positive Bewertung freuen ;)

 
squirrelcgn
25-07-2009, 00:21 
 
Hi Anja,

vielen, vielen Dank! Dein Skript ist genau was ich gesucht habe!!! :rocks:

Jetzt habe ich stundenlang herumprobiert, und befürchte, dass ich jetzt vor dem GLEICHEN Problem stehe wie vorher ("mein" Lösungsansatz)... (ich möchte ja erreichen, dass der gesamte HTML-Code, welcher gerade gehovert ist, ausgegeben/gespeichert wird).

Habe den "document.onkeydown"-Handler so erweitert:

else if (pEvent.keyCode == 32 && currentNode && currentNode.nodeType == 1) {
alert(currentNode.text);
}

(also wenn man "SPACE (32)" drückt, soll der gesamte HTML-Code des currentNode ausgegeben werden)

...und auch currentNode.toString() funktioniert nicht. :-(


Bin ich schon wieder auf dem Holzweg, oder kannst du mir einen Tritt verpassen? ;-)

Danke und Grüße,
Christian

 
AmicaNoctis
25-07-2009, 00:37 
 
Hallo Christian,

ich möchte ja erreichen, dass der gesamte HTML-Code, welcher gerade gehovert ist, ausgegeben/gespeichert wird

Ja, das ist auch ein wenig knifflig. Es gibt zwar bei Elementknoten die Eigenschaft innerHTML, aber das bezieht sich nur auf den Code zwischen
<aktuellesElement att1="val1" att2="val2">
und
</aktuellesElement>.

Beim IE gab es mal (oder gibt es noch) outerHTML, was genau das ist was du willst, aber du kannst es trotzdem auch im FF nachbauen:

Der Ansatz ist der: Man kopiert das Element samt Inhalt. Man erzeugt ein weiteres neues Element und fügt das kopierte als einziges Kind hinzu. Damit ist das innerHTML des neuen Elements gleich dem outerHTML des inneren (kopierten).


var deinElement = ...; // das ist das von dem du den Code haben willst
var kopie = deinElement.cloneNode(true); // true steht für deep copy
document.body.appendChild(document.createElement("div"));
document.body.lastChild.appendChild(kopie);
var deinCode = document.body.lastChild.innerHTML;
document.body.removeChild(document.body.lastChild);


In deinCode findest du dann den HTML-Code von deinElement inkl. Start- und Endtag sowie Attributen.

Gruß,

Anja

 
wahsaga
25-07-2009, 00:58 
 
...und auch currentNode.toString() funktioniert nicht. :-(
Natürlich, das wird auch nie "funktionieren" - da wird immer nur etwas a la "HTMLIrgendwasObject" bei herauskommen.

Auf innerHTML wurdest du doch bereits hingewiesen - wenn dir irgendwas halbwegs brauchbare Ergebnisse liefern wird, dann das (bzw. eine der Abwandlungen davon, die manche Browser vielleicht noch kennen, wie outerHTML o.ä.).

 
squirrelcgn
25-07-2009, 02:40 
 
WOW, danke!! Aber leider habe ich es nicht geschafft, etwas anderes als "undefined" zu erhalten... :-(

Habe im Prinzip dein Skript 1:1 übernommen und den "currentNode" als Input und die Variable "deinCode" als Output gewählt, also so:

//INPUT
var deinElement = currentNode; // das ist das von dem du den Code haben willst

//TRANSFORM
var kopie = deinElement.cloneNode(true); // true steht für deep copy
document.body.appendChild(document.createElement("div"));
document.body.lastChild.appendChild(kopie);
var deinCode = document.body.lastChild.innerHTML;
document.body.removeChild(document.body.lastChild);

//OUTPUT
alert(deinCode);

Wo kann ich ansetzen, wo kann ich evtl. nachschauen? Wie ist currentNode zu interpretieren?

Vielen Dank und Grüße!

 
squirrelcgn
25-07-2009, 02:51 
 
Ich habs!! :-) :-D

Hab es jetzt mit folgender Modifikation gelöst:

function getOuterHTML(object) {

var element;

if (!object) return null;

element = document.createElement("div");

element.appendChild(object.cloneNode(true));

return element.innerHTML;
};

Vielen Dank an Anja und alle anderen!

Grüße!


Alle Zeitangaben in WEZ +2. Es ist jetzt 21:27 Uhr.