Ankündigung

Einklappen
Keine Ankündigung bisher.

plain JS gesetzter Titel kann nicht gelesen werden =(

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • plain JS gesetzter Titel kann nicht gelesen werden =(

    Hallo,

    ich habe ein kleines Script geschrieben, das zulange Texte kürzt und den original Text in das Attribut title packt.
    Das funktioniert bisher alles tadellos (schon mit div. Browsern getestet).

    Das einzige Problem das ich habe, ist das ich aktuell z.B. ein <a>-Element damit behandle, wenn dieses angeklickt wurde soll das Attribut title gelesen werden und es wird immer '' (blank) zurück gegeben. Es wurde aber alles ins DOM übernommen, es werden noch 2 weitere Attribute gesetzt die dann mittels JQ ein Tooltip erzeugen, welcher auch erscheint !
    Das <a>-Element hat beim laden der Seite keinen Titel, würde das setzten der Attribute nicht funktionieren, dürfte auch kein tooltip erscheinen (nur bei verkürzten Elementen erscheint dieses).

    Code:
    element.setAttribute(attr, options.titleLayout.attr[attr].replace('%tit%', textOrg));
    Das ist die besagte Zeile die den Titel setzten, wenn ich nun das Element im DEV-Tool untersuche werden mir auch alle gesetzten Attribute angezeigt (mit Inhalt).
    Wenn ich nach dem Klick das Element debugge kann ich sowohl in plain-js als auch JQ das Attribut in der Console finden und auch etwaige Überprüfungen bestätigen das dieses attribut vorhanden ist, lediglich die ausgabe enthält einen leeren String

    Code:
    <div class="clampAucTit">
    <a id="test_1" target="_self" data-mode="win" href="url..." onclick="contentWindow( $(this) ); return false;">1Erster Versuch - mit einem sehr sehr sehr langem name</a>
    </div>
    
    js-Datei:
    $('document').ready(function(){
        $clamp('clampAucTit', {titleLayout: {attr: {'data-toggle': 'tooltip', 'data-placement': 'top', title:'%tit%'}, class: false}});
    });
    
    function contentWindow( button, onLoadData = false, size = false ){
        console.log(button[0].attributes.hasOwnProperty('title'), '<->', button, '<->', button.html());
        console.log( $(button).attr('title'), '<-' );
    }
    Hier noch fix mein clamp-plugin
    Code:
    /** [-Clamp plugin-] */
    (function(){
        var that = this;
        this.busy = false;
        this.reClampItems = []; // contains all elements for reclamp
        this.reClampTimer = false;
    
        function clamp(item, options) {
            options = options || {};
            options = {
                truncateSteps:      options.truncateSteps || -2, // important set only negative values - that are the charCount that will on each step removed from the end of a string (to find correct lenth)
                truncationChar:     options.truncationChar || '…',
                reClamp:            options.reClamp || true, // reclamp after browser size has changed
                setTitle:           options.setTitle || true,
                titleLayout:        options.titleLayout || {attr: {title:'%tit%'}, class: {}}, // the attribute that contains the original text must have %tit% as value !!! on class set a string with all classes 'foo bar'
                onFinish:           false
            };
    
            // if item a class name find all elements and clamp this
            if( typeof item == 'string' ){
                if( document.readyState == 'loading' ){
                    document.addEventListener("DOMContentLoaded", findElements);
                }else{
                    findElements();
                }
            }else{
                if( !this.busy ){
                    // the wrapper node define the maximum size of text, so check im self the wrapperNode or a parent element (has element childs then its self)
                    var wrapperNode = ( item.childElementCount > 0 ) ? item : item.parentElement,
                        lastNode = ( item.childElementCount == 0 ) ? item : Array.prototype.slice.call(item.children).pop(), // has childes get the last node that contained the text node
                        textNode = lastNode.lastChild,
                        textOrg = textNode.nodeValue,
                        targetSize = {h: Math.max(wrapperNode.clientHeight, wrapperNode.offsetHeight), w: Math.max(wrapperNode.clientWidth, wrapperNode.offsetWidth)};
    
                    if( options.reClamp ){ this.reClampItems.push({wrapperNode:wrapperNode, lastNode:lastNode, textNode:textNode, textOrg:textOrg, targetSize:targetSize, options:options}); }
                }else{
                    // if busy is it reClamp, as first restore main-data
                    options = item.options;
    
                    var wrapperNode = item.wrapperNode,
                        lastNode = item.lastNode,
                        textNode = item.textNode,
                        textOrg = item.textOrg,
                        targetSize = item.targetSize;
    
                    textNode.textContent = textOrg; // set original text to clamp again
                }
    
                var textClamped = textOrg;
    
                // check must truncated
                if( !checkSize() ){
                    truncate();
    
                    // add title to wrapper with the original text - if only needed on clamped text`s
                    if( options.setTitle && lastNode.className.indexOf('title-set') == -1 && textOrg != textClamped ){
                        lastNode.className += ((lastNode.className !== '') ? ' ' : '')+'title-set';
                        setTitle()
                    }
                }
            }
    
            function truncate(){
                textClamped = textClamped.slice(0, options.truncateSteps); // reduce string
                textNode.textContent = textClamped; // update dom to get current size (remove the latest char if it a space)
    
                if( !checkSize() ){
                    truncate();
                }else{
                    textNode.textContent = textClamped.slice(0, -3).replace(/\s+$/,'')+options.truncationChar;
                }
            }
            function setTitle(){
                for( var attr in options.titleLayout.attr ){
                    if( options.titleLayout.attr.hasOwnProperty(attr) ){
                        lastNode.setAttribute(attr, options.titleLayout.attr[attr].replace('%tit%', textOrg));
                    }
                }
    
                // add classes if it defined
                if( options.titleLayout.class !== false ){
                    lastNode.className +=  ' '+options.titleLayout.class;
                }
            }
            function findElements(){
                var items = document.getElementsByClassName(item);
    
                for(var i = 0; i < items.length; i++){
                    if( items[i].className.indexOf('clamped') == -1 ){
                        // add class 'clamped' to skip on next parsing by $clamp('className') (that can be called after has items appended, then we can´t parse the old items again);
                        items[i].className +=  ' clamped';
                        $clamp(items[i], options);
                    }
                }
            }
    
            // return true if we must text clamp
            function checkSize(){
                return (Math.max(lastNode.clientHeight, lastNode.offsetHeight) <= targetSize.h && Math.max(lastNode.clientWidth, lastNode.offsetWidth) <= targetSize.w );
            }
        }
    
        // reClamp automatic
        window.onresize = function(){
            if( that.reClampTimer === false ){
                that.reClamp(); // intiate a new timer
            }else{
                that.reClampTimer = 300; // keep alive the timer
            }
        }
        this.reClamp = function(){
            this.reClampTimer = 300;
    
            var waitExecuting = setInterval(function(){
                that.reClampTimer -= 100;
    
                if( that.reClampTimer <= 0 && !that.busy ){
                    clearInterval(waitExecuting);
                    that.busy = true;
                    that.reClampTimer = false;
                    that.reClampItems.forEach(function(el, i){
                        // check is an element removed before we reClamp this
                        if( el.wrapperNode.isConnected ){
                            clamp(el);
                        }else{
                            that.reClampItems.splice(i, 1);
                        }
    
                        // if resized again before the last run is finished we can break the last run
                        if( that.reClampTimer > 0 ){
                            that.busy = false;
                            return false;
                        }
                    });
                    that.busy = false;
                }
            }, 100);
        }
    
        window.$clamp = clamp;
    })();
    Ist mir ein absolutes Rätzel warum die durch clamp gesetzten Titel nicht gelesen werden können
    Hoffe mir kann da Jemand helfen.

    MfG: Paykoman

  • #2
    Nun ich hatte die Idee das hier durch JS auch eine Refferenz-Abhängigkeit besteht und leider ist dem auch so. Ich habe oben genannte Zeile mal ersetzt und lasse immer 'test' als attribute value setzten, diese wird dann nach dem klick auch ausgegeben. Ist mir zwar ein Rätzel warum es nach dem klick nicht den Inhalt der eben im html Attribut steht benutzt wird es wird scheinbar versucht den Inhalt welches zu beginn in dem Object enthalten war welches die Attribute erstellt zu lesen (was aber ja nicht mehr möglich ist).

    Naja ich suche jetzt mal nach Möglichkeiten die refferenz zu unterbrechen und poste es hier, falls wäre schneller ist, hätte ich nix dagegen.

    ::EDIT::
    Hmm, es liegt garnicht am Object sondern daran das die variable 'textOrg' verwendet wird, auf diese wird wohl refferenziert...

    Kommentar


    • #3
      Bitte ein nachvollziehbares Beispiel auf JSFiddle posten.

      Und in HTML-Code sollte kein JavaScritpt-Code stehen. Das macht den Code nur schwer wart- und nachvollziehbar.

      Kommentar


      • #4
        Zitat von hellbringer Beitrag anzeigen
        Bitte ein nachvollziehbares Beispiel auf JSFiddle posten.

        Und in HTML-Code sollte kein JavaScritpt-Code stehen. Das macht den Code nur schwer wart- und nachvollziehbar.
        Tut es nicht, deshalb steht dort auch "js-Datei:" und kein <script...>...

        Aber gut ich habe den Fehler gefunden, der liegt nicht an meinem Script sondern daran das ich die benötigten Attribute setzte die das JQ-tooltip plugin benötigt.
        Das Plugin ist dann aber bereits geladen worden nach dem mein clamp gelaufen ist, somit muss ich lediglich schauen das nach dem clampen die tooltips neu geparst werden und nicht mehr zu solchen Fehlern führt.

        Kommentar


        • #5
          Zitat von Paykoman Beitrag anzeigen
          Tut es nicht
          Code:
          onclick="contentWindow( $(this) ); return false;"
          Beweisführung abgeschlossen.

          Kommentar


          • #6
            [SIZE="1"]Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.[/SIZE]

            Kommentar

            Lädt...
            X