$().hover.... und Regex

N

Netzwerkidi

Hallo zusammen,

erst einmal allen ein frohes neues Jahr, alles Gute, Gesundheit, Glück und Lebensfreunde!!

Frage 1: Gibt es eine Möglichkeit mit Javascript, das Anzeigen des title-Attributs zu erzwingen?

Hintergrund: Ich verwende jQuerys hover, um damit via Ajax den title-Text, der bis zu diesem Zeitpunkt noch nicht existiert, vom Server zu holen.
Ja gut, nun ist er zwar da, wird aber nicht angezeigt, weil er zum Zeitpunkt, als die Maus in das Feld kam, noch nicht da war. Gehe ich mit der Maus raus und wieder rein, ist er da.
Es geht um Textausschhnitte, die sich hinter URLs verbergen. Man soll natürlich direkt den Text sehen.


Frage 2: Beim Holen des title-Textes werden auch Zeilenumbrüche und zeilenführende Zeichen (vlt. Blanks, vlt. aber auch was anderes) mitgeholt. Der title-Text sieht dann teilweise so aus:


Code:
  text text text text text  text  text

text text text text text  text  text

 text text text text text  text  text




text text text text text  text  text

text text text text text  text  text

Ich habe versucht, ein paar Sachen rauszuholen, aber es funktioniert nicht, vlt. weil ich kein Regex-Experte bin, vlt. auch weil die falschen Zeichen zum Tauschen genommen wurden:

Code:
  var regex1 = /<\S[^>]*>/g;
  var regex2 = /\f\n\r\t\v\s/;
  postcontent = postcontent.replace(regex1,"").replace(regex2,' ');

Weiß einer, wie es geht?
 
Zu Frage 1: Wenn du ebenfalls mit jQuery die Title-Eigenschaft mit einem Wert belegst, wird er doch auch gleich angezeigt.

Zeig doch mal wie der Code jetzt aussieht mit dem du den Wert ermittelst und dann an die Eigenschaft übergibst.
 
Der wird ja erst geholt, wenn ich reingehe.

Hier ist der Code, wie er im Moment aussieht, kann sich noch ändern:

Code:
$('#Block a').hover(function() {
    var $href = $(this).attr('href') || '';
    if (  $(this).parent().parent().hasClass('posts') &&
         !$(this).hasClass('hasTitle') &&
         (typeof $(this).attr('title') == 'undefined' || $(this).attr('title') == false || $(this).attr('title') == '') && 
         !$href == '' &&
          $href.indexOf('.html') > 0 &&
          $href.indexOf('archive.html') < 1 &&
          $(this).find('span').length < 1 ) {
      //alert('1');
      $(this).attr('title', '');
      $(this).append('<span style="display:none"></span>');
      $(this).css({'cursor':'wait'});
      var $span = $(this).find('span');
      getSnippet($span,$href,$(this));
      $(this).attr('title', $span.text());
      if (!$(this).attr('title') == '') {
        $(this).addClass('hasTitle');
        $span.remove();
      }
    }    
    else if (!$(this).attr('title') == '' && $(this).find('span').length < 1) {
      //alert('2');
    }     
    else if ( $(this).attr('title') == '' && $(this).find('span').length > 0 ) {
      //alert('3');
      var $span = $(this).find('span');
      $(this).attr('title', $span.text());
      if (!$(this).attr('title') == '') {
        $(this).addClass('hasTitle');
        $span.remove();
      }
    } 
    else {
      //alert('4');
    }
  });

getSnippet schreibt den geholten Wert in ein Span-Element, der wird dann später ausgelesen und in title übertragen und das Span-Element vernichtet. Das ist nicht anders möglich m. W. wegen der asynchronen Übertragung.
 
So hat ein bisschen gedauert aber dafür habe ich wohl die Lösung gefunden.

Bei der load-Funktion gibt es eine callback-Funktion die ausgeführt wird, wenn die Funktion selber fertig ist. Mit dieser callback-Funktion kannst du den gültigen Wert ermitteln und eintragen.

Javascript:
$(document).ready(function(){

	$("a").hover(function () {
		var index = $(this).attr("id").replace(/link/, "");
		$("#titel").load("search.php?id=" + index,
			function () {
				$("#link" + index).attr("title", $("#titel").html());
			});
	});

});

HTML:
<div id="titel"></div>
<p></p>
<a href="www.wetter.de" id="link1">Wetter</a>
<br />
<a href="www.tutorials.de" id="link2">Tutorials</a>
<br />
<a href="www.google.de" id="link3">Google</a>
<br />
<a href="www.amazon.de" id="link4">Amazon</a>

In diesem Beispiel wird die Zahl als Parameter für die Abfrage in der Datei "search.php" aus der ID ermittelt. Die load-Funktion liest den so ermittelten Wert in den DIV-Container "titel" ein und holt ihn dann mit eben der callback-Funktion und trägst ihn als title-Eigenschaft ein.
 
Thx und - Schluck!
Da muss ich jetzt erst mal drüber brüten.
Mir ist im Augenblick offen gestanden nicht so richtig klar, ob ich das Problem richtig rübergebracht habe, da ich leider gar nicht begriffen habe, was du mir sagen willst ;-(

Code:
$(document).ready(function(){
 
    $("a").hover(function () {
        var index = $(this).attr("id").replace(/link/, ""); // die IDs gibt es gar nicht
        $("#titel").load("search.php?id=" + index,        // Ab hier verstehe ich es nicht mehr  
            function () {
                $("#link" + index).attr("title", $("#titel").html());
            });
    });
 
});



So sieht das Textholen übrigens im Moment aus.

Code:
function getSnippet(codeElement,path,linkElement) {
      var htmlcode = '';
      $.ajax({
        url     : "http://MEINBLOG.blogspot.com/feeds/posts/default?alt=json-in-script&path="+path+"&callback=?",
        type    : 'get', 
        dataType: "jsonp",
        success : function(data) {
          for (var i = 0; i < data.feed.entry.length; i++) {
             
            if ("content" in data.feed.entry[i]){
              var postcontent = data.feed.entry[i].content.$t;
            } else if ("summary" in data.feed.entry[i]){
              var postcontent = data.feed.entry[i].summary.$t;
            } else {
              var postcontent = "";
            }
             
            //var postcontent = data.feed.entry[i].contentSnippet;
            var re = /<\S[^>]*>/g;
            var regex2 = /\f\n\r\t\v\s/;
            postcontent = postcontent.replace(re,"").replace(regex2,' ');
            if (postcontent.length > 500){ // 200
              postcontent = postcontent.substring(0,500);
            }
            htmlcode += postcontent+'...';
          }
          $(codeElement).html(htmlcode);
          $(linkElement).css({'cursor':'default'});
        }
      });
  }
 
Die $.ajax Variante war mir bisher immer viel zu kompliziert und ich habe deshalb nur mit load gearbeitet. Kurz gesagt ist es aber so wie ich das verstanden habe das selbe.

In meinem Beispiel hat jeder der Links eine ID "link" und eine Zahl dahinter. Diese Zahl übergebe ich bei load als Parameter für die Abfrage die in der Seite "search.php" dann ausgeführt wird. Diese Seite/Abfrage liefert mir dann einfach ein Wort welches als title-Eigenschaft angezeigt werden soll.

Javascript:
$("a").hover(function () {

// in dieser Variablen wird die ID des Elements gespeichert welche die
// hover-Funktion aufgerufen hat

    var id = $(this).attr("id");

// mit der load-Funktion die PHP Seite aufrufen die den Wert ermittelt welcher
//als title angezeigt werden soll. param1 und wert1 sind dann einfach die
// Attribute (können natürlich auch mehr sein) welche an die Datei übergeben werden

    $("#id_deines_span").load("deine_datei.php?param1=" + wert1,

// das hier ist die callback-Funktion

        function () {

// durch die Variable id wird wieder das Element angesprochen welches den Aufruf
// der Funktion erzeugt hat. Der Wert der angezeigt wird, steht im span mit der ID
// "id_deines_span"

            $("#" + id).attr("title", $("#id_deines_span").html());
        });
});

NACHTRAG: Bei $.ajax hat man auch die Möglichkeit async = false zu setzen (Default ist true) und auch hier gibt es eine callback-Funktion (complete) die ausgeführt ist wenn der Vorgang abgeschlossen ist.
Lies dir doch nochmal durch was die Funktion so alles hergibt, dann musst du deinen Code womöglich gar nicht groß ändern!?
 
Zuletzt bearbeitet:
Irgendwie will es nicht so richtig, könnte hiermit zu tun haben:

http://stackoverflow.com/questions/3973933/jquery-load-callback-function

You can't do that.

AJAX is asynchronous, meaning that your function will return before the server sends a response.
You need to pass the value to your caller using a callback, the way $.load does.

obwohl weiter oben das Statement offenbar funktioniert:

$("#bdiv").load("bosses.php #icc10n",function(data){
// use the data param
// e.g. $(data).find('#icc10n')
});


Ist ja im Prinzip deine Lösung.

Code:
$('body').append('<a id="testid" href="http://myblog.blogspot.de/meinLink.html">Link<span></span></a>');    
  
    $("#testid").mouseenter(function () {
      var $span =  $(this).find('span');
      var path = $(this).attr('href');
      $('span').load("http://myblog.blogspot.com/feeds/posts/default?alt=json-in-script&path="+path+"&callback=?",
        function (data) {
          for (var i = 0; i < data.feed.entry.length; i++) {
             
            if ("content" in data.feed.entry[i]){
              var postcontent = data.feed.entry[i].content.$t;
            } else if ("summary" in data.feed.entry[i]){
              var postcontent = data.feed.entry[i].summary.$t;
            } else {
              var postcontent = "";
            }
             
            //var postcontent = data.feed.entry[i].contentSnippet;
            var re = /<\S[^>]*>/g;
            var regex2 = /\f\n\r\t\v\s/;
            postcontent = postcontent.replace(re,"").replace(regex2,' ');
            if (postcontent.length > 500){ // 200
              postcontent = postcontent.substring(0,500);
            }
            alert(htmlcode);
            htmlcode += postcontent+'...';
          }
        }
        //$span.attr("title", htmlcode);
      );
    });


Meldung immer: TypeError: data.feed is undefined

Wenn ich den Link im Browser aufrufe, wird ein JSON-Objekt angezeigt, was für "You can't do that. AJAX is asynchronous..." sprechen würde.
 
Zuletzt bearbeitet von einem Moderator:
Wenn ich ehrlich sein soll, ich verstehe nicht so richtig was bei dir passiert wenn die Seite aufgerufen wird und welche Parameter übergeben werden.
Mir ist auch nicht ganz klar welcher Wert zurück geliefert und ausgegeben wird.

Kannst du das nochmal erklären.
 
Ich denke, das Problem ist, dass du synchron zu agieren empfiehlst, was aber in diesem Fall nicht geht, da die Werte eben nur asynchron im JSON-Format geliefert werden .
Inzwischen habe es aber auch soweit.
Ich werde allerdings vom title-Attribut Abstand nehmen und die Info als eine Art Notify ausgeben, da kann ich auch Thumbnails reinpacken.
Falls es dich interessiert: http://stopesm.blogspot.com/ rechte Seite Archiv, Empfohlen und Trend
Kann sein, dass es weiterhin hakelt. Ist halt kein eigener Server mit Dev, Test, Freigabe, Prod...
 
Zuletzt bearbeitet von einem Moderator:
Also es sollte mit meinem obigen Beispiel schon klappen.

So wie ich das sehe hast du in der Datenbank die "Überschrift" und den kompletten Inhalt der Meldung gespeichert. So bald man nun mit der Maus über den Link fährt, wird mit Hilfe von jQuery und einer separaten Datei eine Abfrage an die Datenbank geschickt, die Werte ermittelt und als title eingetragen.

Beispiel der Datenbank:
IDPOSTSNIPPET
1Meldung 1Ganz viel Text für die erste Meldung.
2Meldung 2Auch bei der zweiten Meldung steht viel Text dabei.

In der separaten Datei "deine_datei.php" steht dann:

PHP:
// Die Feldnamen habe ich mal so gewählt weil es bei dir auf der Seite so angezeigt wird.
$sql = "SELECT post, snippet FROM deine_tabelle WHERE id = " .$_GET["id"];
$rs = mysql_query($sql);
// das was hier ausgegeben wird, wird in das span-Tag eingetragen und als title angezeigt.
echo "POST: " .mysql_result($rs, 0, "post");
echo "<br />";
echo "----";
echo "<br />";
echo "SNIPPET: " .mysql_result($rs, 0, "snippet");

und diese Datei wird mit der jQuery-Funktion so aufgerufen:

Javascript:
$("a").hover(function () {
    var id = $(this).attr("id");
    $("#id_deines_span").load("deine_datei.php?id=" + wert1,
        function () {
            $("#" + id).attr("title", $("#id_deines_span").html());
        });
});

Jeder deiner Links liefert die ID des Eintrags in der Datenbank. Mit diesem Parameter wird die separate Datei "deine_datei.php" aufgerufen und die Ausgabe im span-Tag erzeugt und als title-Eigenschaft angezeigt.
 
Zurück