• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

onMouseOver mit Auswirkung auf mehrere Links

Status
Für weitere Antworten geschlossen.

Bernhard

Neues Mitglied
Hallo @ all,

hab mal wieder ein Anfängerproblem, zu dem ich bei Google nicht wirklich was
gefunden habe:

Ich habe eine Seite mit einem Menü (genaugenommen geht es nur um das Submenü)
im Content habe ich kurze Vorschauen (Bild und Text) zu den Seiten, zu denen die
Menüpunkte verlinken. Auch die Vorschauen sind entsprechend verlinkt.

Jetzt soll sich das Aussehen der Links beim MouseOver verändern, wenn ich also in
der Navigation über den ersten Link fahre, soll gleichzeitig auch der erste Vorschautext
hervorgehoben sein, wenn ich über die zweite Vorschau fahre, soll gleichzeitig der
zweite Menüpunkt hervorgehoben sein usw.

Bei onMouseOut soll der ursprüngliche Zustand wiederhergestellt werden (besuchte
Links haben eine andere Farbe...).

Soweit bin ich bisher (bzw. so wenig weit):

HTML (nur die relevanten Abschnitte):
Code:
<li><a href="#" name="link-1">Linktext</a></li>
...
<li>
            <a href="#" name="link-1"><img src="bild.jpg" alt="Alternativtext" width="" height="" border="0" title="" />
            <span>Text</span></a>
</li>
javascript:
Code:
function underline() {
    document.getElementsByTagName("a").onMouseOver = function() {
        document.getElementsByName("link-1").style.textDecoration = 'underline';
        document.getElementsByName("link-1").style.color = '#000000';
        document.getElementsByName("link-2").style.textDecoration = 'underline';
        document.getElementsByName("link-2").style.color = '#000000';
        document.getElementsByName("link-3").style.textDecoration = 'underline';
        document.getElementsByName("link-3").style.color = '#000000';
        document.getElementsByName("link-4").style.textDecoration = 'underline';
        document.getElementsByName("link-4").style.color = '#000000';
        }
    document.getElementsByTagName("a").onMouseOut = function() {
        this.style.textDecoration = ' '; 
        }
    }
window.onload = underline;
Das funktioniert aber nicht. Außerdem ist es mir zu viel Script, ich hätte also da lieber
etwas mit einer Variablen...

Wo sind meine Fehler?

Grüße
Bernhard

P.S.: ideal wäre natürlich, wenn es eine Funktion gäbe, die Elemente mit dem gleichen
Linktext auswählt...
 
Werbung:
getElementsBy(Tag)Name liefert eine NodeList zurück und kein konkretes Element. onmouseover anzuhängen wird also keinen Fehler werfen aber auch nicht funktionieren, da Events nur an konkrete Elemente gehängt werden können.
Du musst also die Rückgabe loopen.

Außerdem möchtest du dein CSS vom JS trennen und mit JS nur Klassen (className) setzen, welche in deinem CSS vordefiniert sind.

Desweiteren ist name für <a>, <img /> und <form> lange missbilligt. Du musst also anständig dein DOM auseinander nehmen oder mit IDs arbeiten.
 
getElementsBy(Tag)Name liefert eine NodeList zurück und kein konkretes Element. onmouseover anzuhängen wird also keinen Fehler werfen aber auch nicht funktionieren, da Events nur an konkrete Elemente gehängt werden können.
Du musst also die Rückgabe loopen.

Außerdem möchtest du dein CSS vom JS trennen und mit JS nur Klassen (className) setzen, welche in deinem CSS vordefiniert sind.

Desweiteren ist name für <a>, <img /> und <form> lange missbilligt. Du musst also anständig dein DOM auseinander nehmen oder mit IDs arbeiten.

Hallo Crash,

danke! Hatte gedacht, dass das für einen Anfänger realisierbar sein könnte.
Wenn ich mal viel Zeit habe, werde ich mal nach den Begriffen googeln.

Grüße
Bernhard
 
Werbung:
Hallo Crash,

so, hab mal meinen alten Thread ausgegraben, weil ich denke, dass das sinnvoller ist,
als einen neuen aufzumachen, da so jeder den Zusammenhang sehen kann (auch
derjenige, der über Google kommt)...

Hab jetzt seit dem ich das Thema hier aufgemacht hatte immer wieder gegoogelt
und viel ausprobiert, aber leider alles erfolglos.

Aktueller Stand:
HTML (nur die relevanten Abschnitte):
Code:
        <ul id="navigation">
            <li><a href="../">Startseite</a></li>
            <li><a href="#">Link</a></li>
            <li><a href="#" class="aktiv">Link</a>
                <ul>
                    <li><a href="../ordner/link-1.php" class="link-underline">Link-1</a></li>
                    <li><a href="../ordner/link-2.php" class="link-underline">Link-2</a></li>
                </ul></li>
            <li><a href="#">Link</a></li>
            <li><a href="#">Link</a></li>
        </ul>

        <ul class="thumbs-liste">
            <li>
            <a href="../ordner/link-1.php" class="thumb-underline"><img src="../img/bild-1.jpg" alt="Alternativtex" width="" height="" border="0" title="" />
            <span>Text 1</span></a>
            </li>
            <li>
            <a href="../ordner/link-2.php" class="thumb-underline"><img src="../img/bild-2.jpg" alt="Alternativtex" width="" height="" border="0" title="" />
            <span>Text 2</span></a>
            </li>
            <li>
            <a href="../ordner/link-3.php" class="thumb-underline"><img src="../img/bild-3.jpg" alt="Alternativtex" width="" height="" border="0" title="" />
            <span>Text 3</span></a>
            </li>
        </ul>
javascript:
Code:
var i = 0;
function initMenu() {
    var navigation = document.getElementById("navigation");
    for(var i=0; a = navigation.getElementsByTagName("a")[i]; i++) {
        if(a.className.search("link-underline") != -1)
        setActivity(a);
    }
    var thumbs = document.getElementsByTagName("a");
    for(var i=0; thisThumb = document.getElementsByTagName("a")[i]; i++) {
        if(thisThumb.className.search("thumb-underline") != -1)
        setActivity(thisThumb);
    }
}
function setActivity(a) {
    a.onMouseOver = mouseOver;
    a.onMouseOut = mouseOut;
}
function setActivity(thisThumb) {
    thisThumb.onMouseOver = mouseOver;
    thisThumb.onMouseOut = mouseOut;
}
function mouseOver() {
    a.className = 'underline';
    thisThumb.className = 'underline';
    return this;
}
function mouseOut() {
    a.className = '';
    thisThumb.className = '';
    return this;
}
window.onload = initMenu;
Die Fehlerkonsole bleibt leer.

Ich hatte auch schon versucht, thisThumb erstmal mit einer Variablen [j] zu machen,
aber das war ebenso erfolglos.

Grüße
Bernhard
 
Edit: Verknüpft Gruppen von Elementen miteinander. (Hier: <a>-Tags anhand des href-Attributs.) Voraussetzung für und Art der Verknüpfung variabel festlegbar.

Verknüpft a-Tags mit Klasse "linked" in #navigation und #thumbs anhand des href-Attributs.

Weitere Erklärungen dazu folgen später. Das IE-kompatibel zu machen, hat mir gerade den letzten Nerv geraubt. Puh. :evil:


Index-Seite:

HTML:
<!DOCTYPE html>

<html>

<head>
    <title>demo</title>

    <link rel="stylesheet" type="text/css" href="styles.css" />

    <script type="text/javascript" src="lib.js"></script>
    <script type="text/javascript" src="init.js"></script>
    <script type="text/javascript">
    /* <![CDATA[ */
    window.onload = function()
    {
        initLinkThumbnails();
    }
    /* ]]> */
    </script>
</head>

<body>
    <ul id="navigation">
        <li><a href="http://www.html.de/">Startseite</a></li>
        <li><a href="#">Link</a></li>
        <li><a href="#" class="aktiv">Link</a>
            <ul>
                <li><a href="http://www.html.de/ordner/link-1.php" class="linked">Link-1</a></li>
                <li><a href="http://www.html.de/ordner/link-2.php" class="linked">Link-2</a></li>
            </ul>
        </li>
        <li><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
    </ul>

    <ul id="thumbs">
        <li>
            <a href="http://www.html.de/ordner/link-1.php" class="linked">
                <img src="http://www.html.de/img/bild-1.jpg" alt="Alternativtext" />
                <span>Text 1</span>
            </a>
        </li>
        <li>
            <a href="http://www.html.de/ordner/link-2.php" class="linked">
                <img src="http://www.html.de/img/bild-2.jpg" alt="Alternativtext" />
                <span>Text 2</span>
            </a>
        </li>
        <li>
            <a href="http://www.html.de/ordner/link-1.php" class="linked">
                <img src="http://www.html.de/img/bild-3.jpg" alt="Alternativtext" />
                <span>Text 3</span>
            </a>
        </li>
    </ul>
</body>

styles.css:

Code:
.selected {
    background: #f00;
    }

lib.js:

Code:
/**
 * Weitere String-Funktionen
 */
function StringUtils() {}

/**
 * Schneidet die angegebenen Zeichen auf beiden Seiten des Strings ab
 *
 * @param str   String Zuzuschneidender String
 * @param chars String (default: \s (Whitespace)) Charakterklasse von Zeichen,
 *                     die abgeschnitten werden sollen
 * @return String Zugeschnittener String
 */
StringUtils.trim = function(str, chars)
{
    return StringUtils.ltrim(StringUtils.rtrim(str, chars), chars);
}

/**
 * Schneidet die angegebenen Zeichen am Anfang des Strings ab
 *
 * @param str   String Zuzuschneidender String
 * @param chars String (default: \s (Whitespace)) Charakterklasse von Zeichen,
 *                     die abgeschnitten werden sollen
 * @return String Zugeschnittener String
 */
StringUtils.ltrim = function(str, chars)
{
    chars = chars || "\\s";
    return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

/**
 * Schneidet die angegebenen Zeichen am Ende des Strings ab
 * 
 * @param str   String Zuzuschneidender String
 * @param chars String (default: \s (Whitespace)) Charakterklasse von Zeichen,
 *                     die abgeschnitten werden sollen
 * @return String Zugeschnittener String
 */
StringUtils.rtrim = function(str, chars)
{
    chars = chars || "\\s";
    return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

/**
 * Funktionen zur Organisation der CSS-Klassen eines Elements
 *
 * @author  Marc Ermshaus <http://ermshaus.org/>
 * @version 2009-09-07
 */
function CssHelper() {}

/**
 * Gibt zurück, ob ein HtmlElement die angegebene CSS-Klasse enthält
 *
 * @param node HtmlElement Zu prüfendes HtmlElement
 * @param cl   String      Zu suchende CSS-Klasse
 * @return bool true, wenn das Element die CSS-Klasse enthält
 */
CssHelper.hasClass = function(node, cl)
{
    var classes = StringUtils.trim(node.className).split(' ');
    for (var i = 0; i < classes.length; i++) {
        if (cl == classes[i]) {
            return true;
        }
    }

    return false;
}

/**
 * Fügt eine CSS-Klasse hinten an die Klassendefinition eines Elements an, falls
 * sie noch nicht vorhanden ist
 *
 * @param node HtmlElement Ziel-HtmlElement
 * @param cl   String      Hinzuzufügende CSS-Klasse
 */
CssHelper.addClass = function(node, cl)
{
    if (!CssHelper.hasClass(node, cl)) {
        node.className += ' ' + cl;
    }
}

/**
 * Entfernt eine CSS-Klasse aus der Klassendefinition eines Elements
 *
 * @param node HtmlElement Ziel-HtmlElement
 * @param cl   String      Zu entfernende CSS-Klasse
 */
CssHelper.removeClass = function(node, cl)
{
    var classes = StringUtils.trim(node.className).split(' ');
    var newClasses = '';
    for (j = 0; j < classes.length; j++) {
        if (cl != classes[j]) {
            newClasses += classes[j] + ' ';
        }
    }
    node.className = newClasses;
}

init.js:

Code:
/**
 * Erstellt Verknüpfungen zwischen Navigation und Thumbnails
 */ 
function initLinkThumbnails() {
    var links  = new Array();
    var thumbs = new Array();
    var result;
    var i;

    // Alle <a>-Elemente mit Klasse "linked" in #navigation ermitteln
    result = document.getElementById('navigation').getElementsByTagName('a');
    for (i = 0; i < result.length; i++) {        
        if (CssHelper.hasClass(result[i], 'linked')) {
            links.push(result[i]);
        }
    }    

    // Alle <a>-Elemente mit Klasse "linked" in #thumbs ermitteln
    result = document.getElementById('thumbs').getElementsByTagName('a');
    for (i = 0; i < result.length; i++) {
        if (CssHelper.hasClass(result[i], 'linked')) {
            thumbs.push(result[i]);
        }
    }
    
    // Voraussetzung für Verknüpfung
    var fcomp = function(a, b) { return (a.href == b.href); };
    
    // Auszuführender Code für Quellelement und Verknüpfungen. Jedem Ziel bei
    // mouseover über Quelle die CSS-Klasse "selected" hinzufügen, bei mouseout
    // wieder entfernen
    var fimpl = function(source, targets)
    {    
        source.onmouseover = function()
        {        
            for (var i = 0; i < targets.length; i++) {
                CssHelper.addClass(targets[i], 'selected');
            }
        }
        source.onmouseout = function()
        {
            for (var i = 0; i < targets.length; i++) {
                CssHelper.removeClass(targets[i], 'selected');
            }
        }
    }
    
    connect(links, thumbs, fcomp, fimpl);   
    connect(thumbs, links, fcomp, fimpl);
}

/**
 * Verknüpft Elemente zweier Mengen anhand einer Bedingung miteinander
 *
 * Beispiel: Eine Seite enthält Bilder und Tags. Beim Überfahren eines Bilds
 * sollen die für dieses Bild gesetzten Tags hervorgehoben werden.
 *    a     - Bilder
 *    b     - Tags
 *    fcomp - "Hat ein Bild einen Tag gesetzt?"
 *    fimpl - "Markiere alle Tags, die diesem Bild zugeordnet sind" 
 *
 * @param a     Array    Quellmenge, deren Elemente mit Elementen der Zielmenge
 *                       verbunden werden sollen (1:n-Zuordnung)
 * @param b     Array    Zielmenge
 * @param fcomp function Bedingung, die erfüllt sein muss, damit ein Element aus
 *                       a auf ein Element aus b verweist. Erwartet:
 *                           function(elementFromA : Object,
 *                                    elementFromB : Object) : bool 
 * @param fimpl function Funktion, die für jedes Element aus a aufgerufen wird,
 *                       das auf mindestens ein Element aus B verweist.
 *                       Erwartet:
 *                           function(elementFromA        : Object,
 *                                    linkedElementsFromB : Array) : void
 *
 * @author  Marc Ermshaus <http://ermshaus.org/>
 * @version 2009-09-07
 */
function connect(a, b, fcomp, fimpl)
{
    for (i = 0; i < a.length; i++) {
        var source  = a[i];
        var targets = new Array();

        for (var j = 0; j < b.length; j++) {
            if (fcomp(a[i], b[j])) {
                targets.push(b[j]);                
            }
        }
 
        if (targets.length > 0) {       
            fimpl(source, targets);
        }
    }
}
 
Zuletzt bearbeitet:
Hallo mermshaus,

danke! Ich bin gespannt auf Deine Erklärung!

Noch ist ein kleiner Fehler drin: mouseover über einen der Links in der Navigation
wirkt sich auf die Thumbs aus, aber Mouseover über einen Thumb wirkt sich nicht
auf die Navigation aus.

Mit Deiner Erklärung hoffe ich, diesen Fehler selbst beheben zu können...

Wie oder wo hast Du JavaScript gelernt?
Ich möcht's auch unbedingt lernen...

Grüße
Bernhard

P.S.: eine Frage gleich: warum hast Du hier [CDATA] drin?
Code:
     <style type="text/css">
    /* <![CDATA[ */
    .selected {
        background: #f00;
        }
    /* ]]> */
    </style>

Erstens habe ich vor, das in ein externes Stylesheet zu schreiben,
zweitens gibt es diese Klasse doch sowieso nur, wenn das Script
ausgeführt werden kann...

Verknüpft a-Tags mit Klasse "linked" in #navigation und #thumbs anhand des href-Attributs.

Weitere Erklärungen dazu folgen später. Das IE-kompatibel zu machen, hat mir gerade den letzten Nerv geraubt. Puh. :evil:

Index-Seite:

HTML:
<!DOCTYPE html>

<html>

<head>
    <title>demo</title>
    <style type="text/css">
    /* <![CDATA[ */
    .selected {
        background: #f00;
        }
    /* ]]> */
    </style>

    <script type="text/javascript" src="lib.js"></script>
    <script type="text/javascript" src="init.js"></script>
    <script type="text/javascript">
    /* <![CDATA[ */
    window.onload = function()
    {
        initLinkThumbnails();
    }
    /* ]]> */
    </script>
</head>

<body>
    <ul id="navigation">
        <li><a href="../">Startseite</a></li>
        <li><a href="#">Link</a></li>
        <li><a href="#" class="aktiv">Link</a>
            <ul>
                <li><a href="../ordner/link-1.php" class="linked">Link-1</a></li>
                <li><a href="../ordner/link-2.php" class="linked">Link-2</a></li>
            </ul>
        </li>
        <li><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
    </ul>

    <ul id="thumbs">
        <li>
            <a href="../ordner/link-1.php" class="linked">
                <img src="../img/bild-1.jpg" alt="Alternativtext" />
                <span>Text 1</span>
            </a>
        </li>
        <li>
            <a href="../ordner/link-2.php" class="linked">
                <img src="../img/bild-2.jpg" alt="Alternativtext" />
                <span>Text 2</span>
            </a>
        </li>
        <li>
            <a href="../ordner/link-1.php" class="linked">
                <img src="../img/bild-3.jpg" alt="Alternativtext" />
                <span>Text 3</span>
            </a>
        </li>
    </ul>
</body>
lib.js:

Code:
function StringUtils() {}

StringUtils.trim = function(str, chars)
{
    return StringUtils.ltrim(StringUtils.rtrim(str, chars), chars);
}

StringUtils.ltrim = function(str, chars)
{
    chars = chars || "\\s";
    return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

StringUtils.rtrim = function(str, chars)
{
    chars = chars || "\\s";
    return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

function CssHelper() {}

CssHelper.hasClass = function(node, cl)
{
    var ret = false;
    var classes = StringUtils.trim(node.className).split(' ');
    for (var i = 0; i < classes.length; i++) {
        if (cl == classes[i]) {
            ret = true;
        }
    }

    return ret;
}

CssHelper.addClass = function(node, cl)
{
    if (!CssHelper.hasClass(node, cl)) {
        node.className += ' ' + cl;
    }
}

CssHelper.removeClass = function(node, cl)
{
    var classes = StringUtils.trim(node.className).split(' ');
    var newClasses = '';
    for (j = 0; j < classes.length; j++) {
        if (cl != classes[j]) {
            newClasses += classes[j] + ' ';
        }
    }
    node.className = newClasses;
}
init.js:

Code:
/**
 *
 *
 */ 
function initLinkThumbnails() {
    var links  = new Array();
    var thumbs = new Array();
    var result;
    var i;

    result = document.getElementById('navigation').getElementsByTagName('a');

    for (i = 0; i < result.length; i++) {
        node = result[i];
        
        if (CssHelper.hasClass(node, 'linked')) {
            links.push(node);
        }
    }    

    result = document.getElementById('thumbs').getElementsByTagName('a');

    for (i = 0; i < result.length; i++) {
        node = result[i];

        if (CssHelper.hasClass(node, 'linked')) {
            thumbs.push(node);
        }
    }

    for (i = 0; i < links.length; i++) {
        links[i]._targets = new Array();

        for (var j = 0; j < thumbs.length; j++) {
            if (links[i].href == thumbs[j].href) {
                links[i]._targets.push(thumbs[j]);
                links[i].onmouseover = function()
                {
                    for (var i = 0; i < this._targets.length; i++) {
                        CssHelper.addClass(this._targets[i], 'selected');
                    }
                }
                links[i].onmouseout = function()
                {
                    for (var i = 0; i < this._targets.length; i++) {
                        CssHelper.removeClass(this._targets[i], 'selected');
                    }
                }
            }
        }
    }
}
 
Werbung:
So, im ersten Post habe ich das Beispiel noch einmal überarbeitet, weiter abstrahiert und durchkommentiert. Erklärungen spare ich mir deshalb und warte Fragen ab. Wer welche hat oder Kritik oder Verbesserungen, nur her damit.

Die connect-Funktion sollte recht universell einsetzbar sein, um alles mögliche zu "vernetzen".

Bernhard schrieb:
Wie oder wo hast Du JavaScript gelernt?
Ich möcht's auch unbedingt lernen...

Das JavaScript, das ich schreibe, ist sicherlich stark verbesserbar oder zu vereinfachen. Ich wende größtenteils Wissen aus anderen Programmiersprachen auf JavaScript an. Die genaue Umsetzung ist immer eine Menge trial & error und Rumgefluche. Dummerweise ist mir nicht mal eine ordentliche Referenzseite zu JavaScript bekannt.

Hab mir auch vorgenommen, es mal besser zu lernen. Deshalb Sachen wie diese Antwort.

Bernhard schrieb:
P.S.: eine Frage gleich: warum hast Du hier [CDATA] drin?

Ich weiß nicht genau, ob das notwendig ist, aber CSS-Code in <style>-Tags kann theoretisch auch reservierte Zeichen enthalten. ">" bei Selektoren und potentiell jedes Zeichen in Kommentaren. Deshalb setzte ich auch hier aus Prinzip CDATA-Tags, wenn es mir nicht zu mühselig ist.

PS: Könntest du den langen Quote-Teil aus deinem Post vielleicht löschen? Ist nicht so wichtig, aber na ja.
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben