Avatar billede andreas13_fam Nybegynder
12. juli 2010 - 18:40 Der er 5 kommentarer og
1 løsning

Få computed width på element ved DOM append - jQuery

Hej jeg har brug for at få width på et input element når den tilføjes til dokumentet via DOM.
Dette er dog åbenbart ikke så lige til efter som man først kan få width når elementet er tilføjet til dokumentet.

Eksempel:


<!DOCTYPE html>
<html lang="da">
    <head>
        <title>Append test</title>
       
        <!-- META Data -->
        <meta charset="utf-8">
               
        <!-- JQuery -->
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <!-- Script -->
        <script type="text/javascript">
            function passElement (elem) {
                if ($(elem).width() == 200) {
                    elem.style.border = '1px solid green';
                } else if ($(elem).width() == 0) {
                    elem.style.border = '1px solid red';               
                } else {
                    elem.style.border = '1px solid blue';               
                }
                elem.value = 'width: '+ $(elem).width();
                return elem;
            }
           
            jQuery.fn.extend({
                append: function() {
                    return this.domManip(arguments, true, function( elem ) {
                        if ( this.nodeType === 1 ) {

                            if ( elem.nodeType === 1) {
                                elem = passElement(elem);
                            }

                            this.appendChild( elem );
                        }
                    });
                }
            });

        </script>
        <style type="text/css">
            /* alle input elementer for bræden 200px */
            input {
                width: 200px;
            }
        </style>
    </head>
    <body>
        <input type="text"><br>
        <script type="text/javascript">
            $(function () {
                passElement(document.getElementsByTagName('input')[0]);
               
                $('<input>')
                    .attr('type','text')
                    .appendTo('body');
            });
        </script>
    </body>
</html>


Det er i orden af passElement først køres lige efter appendChild, bare alle input elementerne "for den grønne ramme".
Avatar billede fant0mas Nybegynder
12. juli 2010 - 19:39 #1
Jeg forstår ikke helt hvad du vil opnå, så du er nok nød til at forklare yderligere.

Hvis bare alle inputs skal have grøn border, så kunne du:

$('input[type="text"]').css('border', 'solid 1px green');


Eller?
Avatar billede andreas13_fam Nybegynder
13. juli 2010 - 08:39 #2
Nej jeg ønsker ikke at få alle elementerne til at være grønne.

Når jeg oprettet et hvilket som helst element, og bruger append(To) i jQuery, så køre min modificering af "jQuery.fn.append" funktionen "passElement". Denne funktion tjekker ved hjælp af "jQuery.width", elementets endelige brede. Den burde være 200px efter som det er angivet i <style>, men er det ikke. Grunden til at den i stedet for 200px er 0, er fordi elementet ikke er tilføjet til dokumentet, med "appendChild" metoden og derfor påvirkes elementet ikke af eventuelle stylesheets.

Bredden på et element kan altså først fås når et element er tilføjet til dokumentet, hvilket også giver mening. Jeg kunne jo have tilføjet elementet til et XML dokument, og så ville elementet ikke være påvirket af "input {width : 200px}".

Det jeg søger er en løsning hvor "passElement" funktionen køres på et tidspunkt sådan at det er muligt at få bredden på elementet.
Som jeg har skrevet er det i orden at "passElement" funktionen først køres efter "appendChild" metoden er brugt. Bare input elementet får den grønne farve.

Med den grønne farve mener jeg selvfølgelig ikke
$('input[type="text"]').css('border', 'solid 1px green')
men at min test funktion (passElement) fungere sådan at hvis elementets bredde er 200px så bliver den grøn, hvis elementets brede er 0 så bliver den rød og hvis der er et uventet resultat så bliver en blå.
Avatar billede intenz Novice
13. juli 2010 - 19:56 #3
Hvis jeg kopierer din 'passElement' ned under 'appendChild', så virker det med det samme (begge bliver grønne). Er der nogen jeg misforståer?
Avatar billede andreas13_fam Nybegynder
14. juli 2010 - 13:48 #4
Jeg beklager meget, eksemplet har været for snævert.
Dette eksempel beskriver det nok bedre.

<!DOCTYPE html>
<html lang="da">
    <head>
        <title>Append test</title>
       
        <!-- META Data -->
        <meta charset="utf-8">
               
        <!-- JQuery -->
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <!-- Script -->
        <script type="text/javascript">
            function passElement (elem) {
                if ($(elem).width() == 200) {
                    elem.style.border = '1px solid green';
                } else if ($(elem).width() == 0) {
                    elem.style.border = '1px solid red';               
                } else {
                    elem.style.border = '1px solid blue';               
                }
                elem.value = 'width: '+ $(elem).width();
                return elem;
            }
           
            jQuery.fn.extend({
                append: function() {
                    return this.domManip(arguments, true, function( elem ) {
                        if ( this.nodeType === 1 ) {
                            this.appendChild( elem );

                            if ( elem.nodeType === 1) {
                                elem = passElement(elem);
                            }
                        }
                    });
                }
            });

        </script>
        <style type="text/css">
            /* alle input elementer for bræden 200px */
            input {
                width: 200px;
            }
        </style>
    </head>
    <body>
                <form action="/" method="get">
                    <p>
                        <label class="labelwidth">Number</label>
                        <input type="text">
                    </p>
                </form>
                <script type="text/javascript">
                    $(function() {
                        $('<p>')
                            .append(
                                $('<label>')
                                    .attr('class','labelwidth')
                                    .text('Number')
                            )
                            .append(
                                $('<input>')
                                    .attr('type','text')
                            )
                            .appendTo('form');
                    });
                </script>
    </body>
</html>
Avatar billede intenz Novice
14. juli 2010 - 20:47 #5
Jeg har prøvet at lege lidt med det. Hvorfor kan jeg ikke kopiere dine indlæg fra eksperten ind i et dokument uden det ødelægger formateringen? :/ Virker med alle andre brugere, mystisk.

Nå, men som jeg ser det kan du først gøre det efter appendTo, da elementerne først bliver synlige her. Laver du din 'passElement' om til en jquery funktion og smider den under der, kan du hente width() som forventet.

Ved at sætte den under der, får du dog parent elementet (<p>) som 'this', og skal derfor selv hente 'children' ud og tjekke dem. Det gør det mindre fleksibelt, men løser trods alt problemet.


<!DOCTYPE html>
<html lang="da">
<head>
<title>Append test</title>

<!-- META Data -->
<meta charset="utf-8">

<!-- JQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

<!-- Script -->
<script type="text/javascript">
jQuery.fn.extend({
    passElement: function() {
       
        var children = this.children();

        for (var i=0; i<children.length; i++) {
            var elem = $(children[i])
            var width = elem.width();
            var border = '';

            if (width == 200) {
                border = '1px solid green';
            } else if (width == 0) {
                border = '1px solid red';
            } else {
                border = '1px solid blue';
            }

            elem.css('border', border);           
        }
    }
});

</script>
<style type="text/css">
/* alle input elementer for bræden 200px */
input {
    width: 200px;
}
</style>
</head>
<body>
<form action="/" method="get">
<p>
<label class="labelwidth">Number</label>
<input type="text" />
</p>
</form>

<script type="text/javascript">
$(function() {
    $('<p>')
    .append(
        $('<label />')
        .attr('class','labelwidth')
        .text('Number')
    )
    .append(
        $('<input />')
        .attr('type','text')

    )
    .appendTo('form')
    .passElement();
});
</script>
</body>
</html>
Avatar billede andreas13_fam Nybegynder
15. juli 2010 - 16:55 #6
Det er måske fordi jeg arbejder på Mac med UNIX linjeskrift, som kun betegnes som \n og ikke \r\n, sammen med at jeg bruger {div}{pre} (erstat { med [), men det er bare et gæt.

Når men dit forslag med at først at køre passElement til sidst virker, jeg fortrækker dog denne løsning.

<!DOCTYPE html>
<html lang="da">
    <head>
        <title>Append test</title>
       
        <!-- META Data -->
        <meta charset="utf-8">
               
        <!-- JQuery -->
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <!-- Script -->
        <script type="text/javascript">
           
            window.setColor = function (elem) {
                if ($(elem).width() == 200) {
                    elem.style.border = '2px solid green';
                } else if ($(elem).width() == 0) {
                    elem.style.border = '1px solid red';               
                } else {
                    elem.style.border = '1px solid blue';               
                }
                elem.value = 'width: '+ $(elem).width();           
            };
           
            function passElement (elem) {
               
                //Tjekker om elementet tilføjes til dokumentet ved denne append
                if (elem.style.width !== '0' && $(elem).width() !== 0) {
                   
                    //Finder element-børn
                    var nodes = elem.getElementsByTagName('*');
                    //Køre funktion på elementer
                    for (var i=0;i<nodes.length;i++) {
                        window.setColor(nodes[i]);
                    }
                    window.setColor(elem);
                }
           
                //Retunere det modificerede element
                return elem;
            }
           
            jQuery.fn.extend({
                append: function() {
                    return this.domManip(arguments, true, function( elem ) {
                        if ( this.nodeType === 1 ) {
                            this.appendChild( elem );
                           
                            //Tjekker om node er et elemenet
                            if ( elem.nodeType === 1) {
                                elem = passElement(elem);
                            }
                        }
                    });
                },
               
                prepend: function () {
                    return this.domManip(arguments, true, function (elem) {
                        if (this.nodeType === 1) {
                            this.insertBefore(elem, this.firstChild);

                            //Tjekker om node er et elemenet
                            if ( elem.nodeType === 1) {
                                elem = passElement(elem);
                            }
                        }
                    });
                }

            });

        </script>
        <style type="text/css">
            /* alle input elementer for bræden 200px */
            input {
                width: 200px;
            }
        </style>
    </head>
    <body>
                <form action="/" method="get">
                    <p>
                        <label class="labelwidth">Number</label>
                        <input type="text">
                    </p>
                </form>
                <script type="text/javascript">
                    $(function() {
                        $('<p>')
                            .append(
                                $('<label>')
                                    .attr('class','labelwidth')
                                    .text('Number')
                            )
                            .append(
                                $('<input>')
                                    .attr('type','text')
                            )
                            .appendTo('form');
                    });
                </script>
    </body>
</html>

Hvor den først køre når den kan få $.width() til ikke at være '0'. Jeg kunne dog forestille mig at fx med display:none at det vil give nogle problemer. Måske du kan komme i tanke om en bedre test til at finde ud af om element er tilføjet til dokumentet.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester