JQuery CSS-plug-in die berekende elementenstijl naar pseudo-clone die element retourneert?

Ik ben op zoek naar een manier met behulp van jQuery om een ​​object van berekende stijlen voor het 1e gematchte element terug te sturen. Ik kan dit object dan doorgeven aan een andere oproep van de CSS-methode van JQuery.

Bijvoorbeeld, met breedte , kan ik het volgende doen om de 2 DIV’s te maken dezelfde breedte:

$('#div2').width($('#div1').width());

Het zou leuk zijn als ik een tekstinvoer zou kunnen maken, lijken op een bestaande overspanning :

$('#input1').css($('#span1').css());

Waar. CSSS () zonder argument retourneert een object dat kan worden doorgegeven aan .css (obj ) .

(Ik kan hiervoor geen jQuery-plug-in vinden, maar het lijkt erop dat het zou moeten bestaan. Als het niet bestaat, zal ik de mijne beneden in een plug-in zetten en posten met alle eigenschappen die ik gebruik. )

In principe wil ik pseudo-klonen bepaalde elementen maar gebruik een andere tag . Ik heb bijvoorbeeld een LI-element dat ik een invoerelement erover wil verbergen en plaatsen die er hetzelfde uitziet. Wanneer de gebruikerstypen, het lijkt erop dat ze het element inline bewerken.

Ik ben ook open voor andere benaderingen voor dit pseudo-kloningsprobleem voor bewerking. Alle suggesties?

Hier is wat ik momenteel heb. Het enige probleem krijgt gewoon alle mogelijke stijlen. Dit kan een belachelijke lange lijst zijn.


jQuery.fn.css2 = jQuery.fn.css;
jQuery.fn.css = function() {
    if (arguments.length) return jQuery.fn.css2.apply(this, arguments);
    var attr = ['font-family','font-size','font-weight','font-style','color',
    'text-transform','text-decoration','letter-spacing','word-spacing',
    'line-height','text-align','vertical-align','direction','background-color',
    'background-image','background-repeat','background-position',
    'background-attachment','opacity','width','height','top','right','bottom',
    'left','margin-top','margin-right','margin-bottom','margin-left',
    'padding-top','padding-right','padding-bottom','padding-left',
    'border-top-width','border-right-width','border-bottom-width',
    'border-left-width','border-top-color','border-right-color',
    'border-bottom-color','border-left-color','border-top-style',
    'border-right-style','border-bottom-style','border-left-style','position',
    'display','visibility','z-index','overflow-x','overflow-y','white-space',
    'clip','float','clear','cursor','list-style-image','list-style-position',
    'list-style-type','marker-offset'];
    var len = attr.length, obj = {};
    for (var i = 0; i < len; i++) 
        obj[attr[i]] = jQuery.fn.css2.call(this, attr[i]);
    return obj;
}

EDIT: Ik gebruik nu de bovenstaande code voor een tijdje. Het werkt goed en gedraagt ​​zich precies zoals de originele CSS-methode met één uitzondering: als 0 args worden doorgegeven, retourneert het het berekende stijlobject.

Zoals u kunt zien, roept het onmiddellijk de originele CSS-methode op als dat het geval is dat van toepassing is. Anders krijgt het de berekende stijlen van alle vermelde eigenschappen (verzameld vanuit de berekende stijllijst van Firebug). Hoewel het een lange lijst van waarden krijgt, is het vrij snel. Ik hoop dat het nuttig is voor anderen.


Antwoord 1, Autoriteit 100%

Twee jaar later, maar ik heb de oplossing waarnaar u op zoek bent. Hier is een plug-in die ik heb geschreven (door de functie van een andere kerel in plugin-formaat) te wikkelen) die precies doet wat je wilt, maar krijgt alle mogelijke stijlen in alle browsers, zelfs ie.

jquery.getStyleObject.js:

/*
 * getStyleObject Plugin for jQuery JavaScript Library
 * From: http://upshots.org/?p=112
 *
 * Copyright: Unknown, see source link
 * Plugin version by Dakota Schneider (http://hackthetruth.org)
 */
(function($){
    $.fn.getStyleObject = function(){
        var dom = this.get(0);
        var style;
        var returns = {};
        if(window.getComputedStyle){
            var camelize = function(a,b){
                return b.toUpperCase();
            }
            style = window.getComputedStyle(dom, null);
            for(var i=0;i<style.length;i++){
                var prop = style[i];
                var camel = prop.replace(/\-([a-z])/g, camelize);
                var val = style.getPropertyValue(prop);
                returns[camel] = val;
            }
            return returns;
        }
        if(dom.currentStyle){
            style = dom.currentStyle;
            for(var prop in style){
                returns[prop] = style[prop];
            }
            return returns;
        }
        return this.css();
    }
})(jQuery);

Basisgebruik is vrij eenvoudig:

var style = $("#original").getStyleObject(); // copy all computed CSS properties
$("#original").clone() // clone the object
    .parent() // select it's parent
    .appendTo() // append the cloned object to the parent, after the original
                // (though this could really be anywhere and ought to be somewhere
                // else to show that the styles aren't just inherited again
    .css(style); // apply cloned styles

Hopelijk helpt dat.


Antwoord 2, autoriteit 37%

Het is geen jQuery, maar in Firefox, Opera en Safari kunt u window.getComputedStyle(element)gebruiken om de berekende stijlen voor een element te krijgen en in IE<=8 kunt u element.currentStyle. De geretourneerde objecten zijn in elk geval anders en ik weet niet zeker hoe goed ze werken met elementen en stijlen die zijn gemaakt met Javascript, maar misschien zijn ze nuttig.

In Safari kun je het volgende doen, wat best netjes is:

document.getElementById('b').style.cssText = window.getComputedStyle(document.getElementById('a')).cssText;

Antwoord 3, autoriteit 8%

Ik weet niet of je blij bent met de antwoorden die je tot nu toe hebt gekregen, maar ik was dat niet en de mijne zal je misschien ook niet bevallen, maar het kan iemand anders helpen.

Na te hebben nagedacht over het “klonen” of “kopiëren” van de stijlen van elementen van de ene naar de andere, ben ik me gaan realiseren dat het niet erg optimaal was om door n te lussen en toe te passen op n2, maar we zijn min of meer zit hiermee vast.

Als je merkt dat je met deze problemen wordt geconfronteerd, hoef je zelden ALLE stijlen van het ene element naar het andere te kopiëren… je hebt meestal een specifieke reden om ‘sommige’ stijlen toe te passen.

Dit is waar ik naar ben teruggekeerd:

$.fn.copyCSS = function( style, toNode ){
  var self = $(this);
  if( !$.isArray( style ) ) style=style.split(' ');
  $.each( style, function( i, name ){ toNode.css( name, self.css(name) ) } );
  return self;
}

Je kunt een door spaties gescheiden lijst met CSS-attributen als het eerste argument doorgeven en het knooppunt waarnaar je ze wilt klonen als het tweede argument, zoals zo:

$('div#copyFrom').copyCSS('width height color',$('div#copyTo'));

Alles wat daarna nog “niet goed uitgelijnd” lijkt te zijn, zal ik proberen op te lossen met stylesheets om mijn J’s niet vol te proppen met te veel verkeerd uitgevoerde ideeën.


Antwoord 4, autoriteit 5%

Nu ik wat tijd heb gehad om het probleem te onderzoeken en beter te begrijpen hoe de interne css-methode van jQuery werkt, lijkt wat ik heb gepost goed genoeg te werken voor het gebruik dat ik noemde.

Er is voorgesteld dat je dit probleem met CSS kunt oplossen, maar ik denk dat dit een meer algemene oplossing is die in ieder geval zal werken zonder dat je klassen hoeft te verwijderen of je CSS hoeft bij te werken.

Ik hoop dat anderen het nuttig vinden. Laat het me weten als je een bug vindt.


Antwoord 5, autoriteit 5%

Ik vind je antwoord op Quickredfox leuk. Ik moest wat CSS kopiëren, maar niet meteen, dus ik heb het aangepast om de “toNode” optioneel te maken.

$.fn.copyCSS = function( style, toNode ){
  var self = $(this),
   styleObj = {},
   has_toNode = typeof toNode != 'undefined' ? true: false;
 if( !$.isArray( style ) ) {
  style=style.split(' ');
 }
  $.each( style, function( i, name ){ 
  if(has_toNode) {
   toNode.css( name, self.css(name) );
  } else {
   styleObj[name] = self.css(name);
  }  
 });
  return ( has_toNode ? self : styleObj );
}

Als je het zo noemt:

$('div#copyFrom').copyCSS('width height color');

Vervolgens retourneert het een object met uw CSS-declaraties die u later kunt gebruiken:

{
 'width': '140px',
 'height': '860px',
 'color': 'rgb(238, 238, 238)'
}

Bedankt voor het startpunt.


Antwoord 6, autoriteit 5%

Multifunctionele .css()

Gebruik

$('body').css();        // -> { ... } - returns all styles
$('body').css('*');     // -> { ... } - the same (more verbose)
$('body').css('color width height')  // -> { color: .., width: .., height: .. } - returns requested styles
$('div').css('width height', '100%')  // set width and color to 100%, returns self
$('body').css('color')  // -> '#000' - native behaviour

Code

(function($) {
    // Monkey-patching original .css() method
    var nativeCss = $.fn.css;
    var camelCase = $.camelCase || function(str) {
        return str.replace(/\-([a-z])/g, function($0, $1) { return $1.toUpperCase(); });
    };
    $.fn.css = function(name, value) {
        if (name == null || name === '*') {
            var elem = this.get(0), css, returns = {};
            if (window.getComputedStyle) {
                css = window.getComputedStyle(elem, null);
                for (var i = 0, l = css.length; i < l; i++) {
                    returns[camelCase(css[i])] = css.getPropertyValue(css[i]);
                }
                return returns;
            } else if (elem.currentStyle) {
                css = elem.currentStyle;
                for (var prop in css) {
                    returns[prop] = css[prop];
                }
            }
            return returns;
        } else if (~name.indexOf(' ')) {
            var names = name.split(/ +/);
            var css = {};
            for (var i = 0, l = names.length; i < l; i++) {
                css[names[i]] = nativeCss.call(this, names[i], value);
            }
            return arguments.length > 1 ? this : css;
        } else {
            return nativeCss.apply(this, arguments);
        }
    }
})(jQuery);

Het hoofdidee is ontleend aan Dakota’s& HexInteractive’santwoorden.


Antwoord 7, autoriteit 5%

Ik wilde alleen een extensie toevoegen aan de code die door Dakota is ingediend.

Als je een element wilt klonen met alle toegepaste stijlen en alle onderliggende elementen, dan kun je de volgende code gebruiken:

/*
 * getStyleObject Plugin for jQuery JavaScript Library
 * From: http://upshots.org/?p=112
 *
 * Copyright: Unknown, see source link
 * Plugin version by Dakota Schneider (http://hackthetruth.org)
 */
(function($){
    $.fn.getStyleObject = function(){
        var dom = this.get(0);
        var style;
        var returns = {};
        if(window.getComputedStyle){
            var camelize = function(a,b){
                return b.toUpperCase();
            }
            style = window.getComputedStyle(dom, null);
            for(var i=0;i<style.length;i++){
                var prop = style[i];
                var camel = prop.replace(/\-([a-z])/g, camelize);
                var val = style.getPropertyValue(prop);
                returns[camel] = val;
            }
            return returns;
        }
        if(dom.currentStyle){
            style = dom.currentStyle;
            for(var prop in style){
                returns[prop] = style[prop];
            }
            return returns;
        }
        return this.css();
    }
    $.fn.cloneWithCSS = function() {
        var styles = {};
        var $this = $(this);
        var $clone = $this.clone();
        $clone.css( $this.getStyleObject() );
        var children = $this.children().toArray();
        var i = 0;
        while( children.length ) {
            var $child = $( children.pop() );
            styles[i++] = $child.getStyleObject();
            $child.children().each(function(i, el) {
                children.push(el);
            })
        }
        var cloneChildren = $clone.children().toArray()
        var i = 0;
        while( cloneChildren.length ) {
            var $child = $( cloneChildren.pop() );
            $child.css( styles[i++] );
            $child.children().each(function(i, el) {
                cloneChildren.push(el);
            })
        }
        return $clone
    }
})(jQuery);

Dan kunt u gewoon doen: $clone = $("#target").cloneWithCSS()


Antwoord 8, Autoriteit 3%

Geweldige functie door het OP. Ik heb het enigszins gewijzigd, zodat u kunt kiezen welke waarden u wilt retourneren.

(function ($) {
    var jQuery_css = $.fn.css,
        gAttr = ['font-family','font-size','font-weight','font-style','color','text-transform','text-decoration','letter-spacing','word-spacing','line-height','text-align','vertical-align','direction','background-color','background-image','background-repeat','background-position','background-attachment','opacity','width','height','top','right','bottom','left','margin-top','margin-right','margin-bottom','margin-left','padding-top','padding-right','padding-bottom','padding-left','border-top-width','border-right-width','border-bottom-width','border-left-width','border-top-color','border-right-color','border-bottom-color','border-left-color','border-top-style','border-right-style','border-bottom-style','border-left-style','position','display','visibility','z-index','overflow-x','overflow-y','white-space','clip','float','clear','cursor','list-style-image','list-style-position','list-style-type','marker-offset'];
    $.fn.css = function() {
        if (arguments.length && !$.isArray(arguments[0])) return jQuery_css.apply(this, arguments);
        var attr = arguments[0] || gAttr,
            len = attr.length,
            obj = {};
        for (var i = 0; i < len; i++) obj[attr[i]] = jQuery_css.call(this, attr[i]);
        return obj;
    }
})(jQuery);

Kies welke waarden u wilt door uw eigen array op te geven: $().css(['width','height']);


Antwoord 9

$.fn.cssCopy=function(element,styles){
var self=$(this);
if(element instanceof $){
    if(styles instanceof Array){
        $.each(styles,function(val){
            self.css(val,element.css(val));
        });
    }else if(typeof styles===”string”){
        self.css(styles,element.css(styles));
    }
}
return this;
};

Gebruik voorbeeld

$("#element").cssCopy($("#element2"),['width','height','border'])

Other episodes