2010-09-27 25 views
9

Tengo una hoja de estilo externa que aplica algunos estilos a un elemento dado. Quiero poder mover esos estilos (usando JavaScript) a un elemento completamente diferente, sin tener conocimiento previo de los estilos que se están aplicando.¿Cómo mover todos los estilos CSS calculados de un elemento y aplicarlos a un elemento diferente usando JavaScript?

El CSS:

td { padding: 5px } 
div { } 

El HTML:

<td> 
    <div> 
     Apply the TD styles to this DIV (instead of the TD). 
    </div> 
</td> 

La JavaScript:

$(document).ready(function(){ 
    $('tr').children('td').each(function(){ 
     //move the td styles to div 
    }); 
}); 

¿Cómo se puede lograr esto?

Actualización: Para ser claros, no tengo control sobre el CSS. No tengo forma de saber qué estilos se pueden aplicar. El problema que estoy tratando de resolver es poder tomar un elemento y copiar sus estilos (que pueden ser desconocidos) y aplicarlos a un elemento diferente.

+0

¿Cómo va a seleccionar que un elemento? –

+0

Proporcione más detalles sobre el caso de uso. En otras palabras, ¿por qué? –

+0

si se calcula o se hereda, no podrá simplemente eliminar un estilo. Un CSS en una clase no puede eliminarse de esta manera usando '.removeAttr ('style')'. también puede encontrar algunas respuestas interesantes aquí http://stackoverflow.com/questions/4781410/jquery-how-to-get-all-styles-css-defined-within-internal-external-document-w – TecHunter

Respuesta

1

EDIT: Código corregida

$('div').attr('style', $('td').attr('style')); 

Si desea mover sólo tiene que añadir esta línea después

$('td').attr('style', ''); 

Soy consciente de que esto parece artificiosa pero no tengo otros selectores para trabajar aquí. Normalmente querrías hacer esto con un id o una clase en lugar del atributo real.

+0

Esto no mueve el estilo, se copia. – SamStephens

+0

El título dice 'copiar' aunque – stagas

+0

He reformulado la pregunta para reflejar mejor lo que estoy tratando de preguntar. – Andrew

2

EDIT: Esta respuesta se escribió antes de que se aclarara la pregunta.

Dale sus identificadores de elementos, como esto:

<td id="td_element" style="padding:5px"> 
    <div id="div_element"> 
     Apply the TD styles to this DIV (instead of the TD). 
    </div> 
</td> 

y el uso

var td_element = $('#td_element') 
$('#div_element').attr('style', td_element.attr('style')); 
td_element.removeAttr('style'); 

Por supuesto, se puede utilizar una clase en lugar - o puede que tenga los elementos de código JavaScript anterior. Tendrá que decidir la mejor manera de hacer referencia a los elementos usted mismo.

+0

¿funcionará esto si los estilos se están aplicando desde una hoja de estilo externa? – Andrew

+1

No, no es así, ya que eso no es lo que pediste. Como puede ver en este ejemplo, aplicar los estilos es fácil. Sin embargo, resolver los estilos aplicados a un elemento incluido en las hojas de estilo es bastante complicado. Vea esta pregunta: http://stackoverflow.com/questions/395341/get-element-stylesheet-style-in-javascript. Tomaría el consejo que figura en la respuesta aceptada para esa publicación: "¿Tal vez sería mejor dar un paso atrás y preguntar por qué alguna vez necesitarías algo así?" – SamStephens

+0

y @Andrew si los estilos se definieron a través de clases que estaban restringidas a elementos 'td' como' td.someclass {..} ', entonces podría eliminar la clase de' td' y aplicarla al 'div'. Mire [addClass()] (http://api.jquery.com/addClass/) y [removeClass()] (http://api.jquery.com/removeClass/) –

-1

y una solución más generalizada de las respuestas proporcionadas ..

HTML

<td style="padding:5px"> 
    <div class="inherit"> 
     Apply the TD styles to this DIV (instead of the TD). 
    </div> 
</td> 

JS

$('.inherit') 
    .attr('style', $(this) 
        .parents('td') 
        .attr('style') 
     ) 
    .parents('td') 
    .removeAttr('style'); 
+0

He reformulado la pregunta para reflejar mejor lo que estoy tratando de preguntar. – Andrew

+0

@Andrew, eche un vistazo a este http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript pero creo que simplemente debe cambiar su CSS de acuerdo –

1

No mueva los estilos es mi respuesta corta - encontrar otra forma. ¿Puedes cargar otra hoja de estilo después de cargar la hoja de estilo? Si es así, agregue una hoja de estilo que anule el relleno de td y div definido en la hoja de estilos a la que tiene que hacer referencia.

+0

seguro, hay muchas maneras diferentes de mover los estilos, pero el punto de la pregunta es encontrar la manera de usar javascript – Andrew

+0

Seguramente el objetivo de la pregunta es resolver cualquier problema que tengas? Estoy sugiriendo que intentar mover los estilos usando javascript será doloroso y frágil, y si puede encontrar una manera de resolver su problema sin hacer esto, tendrá una solución mejor y más duradera. – SamStephens

+0

El problema que estaba tratando de resolver se resolvió hace mucho tiempo con un enfoque diferente. Estoy haciendo la pregunta porque me gustaría saber la respuesta al uso de esta técnica específica. – Andrew

0

¿Qué hay de aplicar el estilo TD real a una clase? Luego solo modifica la clase del TD y los DIVs. ¿O no tienes acceso a la hoja de estilos?

El CSS:

.class_name { padding: 5px } 

El HTML:

<td class="class_name"> 
    <div> 
     Apply the TD styles to this DIV (instead of the TD). 
    </div> 
</td> 

La JavaScript:

$(document).ready(function(){ 
    $('.class_name').removeClass('class_name').children('div').addClass('class_name'); 
}); 
+0

Gracias por tu respuesta, pero ese no es realmente el problema que trato de resolver. – Andrew

2

sé que esto tendrán un aspecto áspero, pero funciona. Inicialmente, copiar todos los estilos calculados desde <td> y aplicarlos a <div> es fácil con this plugin from Mike Dunn. El inconveniente es eliminar los estilos del <td> después de que se hayan copiado. From what I can tell, lo único que puede hacer es restablecerlos manualmente a los valores predeterminados con .css().

Working Example

$.fn.copyCSS = function (source) { 
    var dom = $(source).get(0); 
    var dest = {}; 
    var style, prop; 
    if (window.getComputedStyle) { 
     var camelize = function (a, b) { 
       return b.toUpperCase(); 
     }; 
     if (style = window.getComputedStyle(dom, null)) { 
      var camel, val; 
      if (style.length) { 
       for (var i = 0, l = style.length; i < l; i++) { 
        prop = style[i]; 
        camel = prop.replace(/\-([a-z])/, camelize); 
        val = style.getPropertyValue(prop); 
        dest[camel] = val; 
       } 
      } else { 
       for (prop in style) { 
        camel = prop.replace(/\-([a-z])/, camelize); 
        val = style.getPropertyValue(prop) || style[prop]; 
        dest[camel] = val; 
       } 
      } 
      return this.css(dest); 
     } 
    } 
    if (style = dom.currentStyle) { 
     for (prop in style) { 
      dest[prop] = style[prop]; 
     } 
     return this.css(dest); 
    } 
    if (style = dom.style) { 
     for (prop in style) { 
      if (typeof style[prop] != 'function') { 
       dest[prop] = style[prop]; 
      } 
     } 
    } 
    return this.css(dest); 
}; 

$('td').click(function() { 
    $('div').copyCSS('td'); 

    $('td').removeAttr('style'); 

    $("td").css({ 
     'font-family': 'none', 
      'font-size': 'none', 
      'font-weight': 'none', 
      'font-style': 'none', 
      'color': '#000', 
      'text-transform': 'none', 
      'text-decoration': 'none', 
      'letter-spacing': 'none', 
      'word-spacing': 'none', 
      'line-height': 'none', 
      'text-align': 'none', 
      'vertical-align': 'none', 
      'direction': 'none', 
      'background-color': 'transparent', 
      'background-image': 'none', 
      'background-repeat': 'none', 
      'background-position': 'none', 
      'background-attachment': 'none', 
      'opacity': '1', 
      'width': 'none', 
      'height': 'none', 
      'top': '', 
      'right': '', 
      'bottom': '', 
      'left': '', 
      'margin-top': '0', 
      'margin-right': '0', 
      'margin-bottom': '0', 
      'margin-left': '0', 
      'padding-top': '0', 
      'padding-right': '0', 
      'padding-bottom': '0', 
      'padding-left': '0', 
      'border-top-width': '0', 
      'border-right-width': '0', 
      'border-bottom-width': '0', 
      'border-left-width': '0', 
      'border-top-color': '0', 
      'border-right-color': '0', 
      'border-bottom-color': '0', 
      'border-left-color': '0', 
      'border-top-style': '0', 
      'border-right-style': '0', 
      'border-bottom-style': '0', 
      'border-left-style': '0', 
      'position': 'static', 
      'display': '', 
      'visibility': 'visible', 
      'z-index': 'auto', 
      'overflow-x': 'auto', 
      'overflow-y': 'auto', 
      'white-space': 'normal', 
      'clip': 'auto', 
      'float': 'none', 
      'clear': 'none', 
      'cursor': 'default', 
      'list-style-image': 'none', 
      'list-style-position': '0', 
      'list-style-type': 'disc', 
      'marker-offset': '', 
      'padding': '0', 
      'transition': 'none', 
      'border-radius': 'none' 
    }); 
}); 

Nota: obviamente No he incluido un restablecimiento de todos los estilos posibles.

+0

Ese es uno de los códigos más horribles que he visto en mucho tiempo. ¿Por qué no crear una nueva regla de hoja de estilo basada en window.getComputedStyle (devuelve un 'CSSStyleDeclaration' que puede usar para este fin) y establecer esa clase en el elemento de destino? Además, no estoy seguro de que el OP signifique "mover" estilos para que el elemento original se reinicie completamente en una pizarra en blanco. ¿Por qué querría eso? –

+0

@torazaburo Sé que se ve horrible ... y sinceramente, no puedo pensar en un buen caso de uso para ello, pero a juzgar por la pregunta y algunos de los [comentarios] (http://stackoverflow.com/questions/ 3808400/how-to-move-all-computed-css-styles-from-one-element-and-apply-them-to-a-differe/16995257? Noredirect = 1 # comment4039343_3808413) en las otras respuestas, parecía como si el OP estaba buscando eliminar todos los estilos de un elemento y aplicarlos a otro. Me encantaría ver una mejor manera de hacerlo, si sabes uno, publica una respuesta. – apaul

0

Usted puede probar los siguientes pasos para copiar los estilos definidos para el elemento en particular en hojas de estilo y <style> etiquetas (código es poco larga):

  1. obtener el contenido de las hojas de estilo originales usando ajax. y el contenido de cada uno <style> etiquetas
  2. analizar el contenido css en una matriz
  3. Para cada uno de los selectores en la hoja de estilo analizada, comparar es elemento DOM con el elemento DOM objetivo (de la que está copiando los estilos). si alguno de ellos de los partidos, a continuación, aplicar estilos correspondientes a mathced selector para el elemento deseado

Aquí está el código:

<html> 
    <head> 
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> 
     <style> 
     #source { width: 100px; height: 100px; background-color: black; } 
     </style> 
     <link rel="stylesheet" href="style.css"> 
    </head> 
    <body> 
     <table> 
      <tr> 
       <td id="source"></td> 
      </tr> 
     </table> 
     <div id="target"></div> 
    </body> 

    <script> 
    var source = $('#source'); // source 
    var target = $('#target'); // target 

    $('link[rel="stylesheet"]').each(function() { 
      $.get($(this).attr('href'), {}, function(data) { 
       var css_obj = parse_css(data); 
       copy_css(css_obj, source, target); 
      }); 
    }); 

    $('style').each(function() { 
     var css = $(this).text(); 
     var css_obj = parse_css(css); 
     copy_css(css_obj, source, target); 
    }) 

    function copy_css(css_obj, source, target) { 
     for(selector in css_obj) { 
      if($(selector)[0] === source[0]) { // compare raw dom elements 
       for(prop in css_obj[selector]) { 
        target.css(prop, css_obj[selector][prop]); 
       } 
      }        
     } 
    } 


    function parse_css(css) { 
     var css = css.replace(/[\s\n\t]+/g, ' '); // remove extra spaces, tabs and newlines 
     css = css.replace(/\/\*(.|\n)+\*\//g, ''); // remove comments 
     css = css.split('}'); // split into groups 
     var css_obj = []; // array to hold parsed css 

     for(i in css) { 
      if(css[i] == false) continue; 
      var chunks = css[i].split('{'); 
      var selector = $.trim(chunks[0]); 
      var style_defs = []; 
      chunks = chunks[1].split(';'); 
      for(j in chunks) { 
       if(chunks[j] == false) continue; 
       var style_def = chunks[j].split(':'); 
       var property = $.trim(style_def[0]); 
       var value = $.trim(style_def[1].replace(/\;$/, '')); 
       style_defs[property] = value; 
      } 
      css_obj[selector] = style_defs; 
     } 
     return css_obj; 
    } 

    </script> 

8

Esta es una solución que me di cuenta, que mezcla el documento .defaultView.getComputedStyle y de jQuery css():

<!-- index.html --> 
<!DOCTYPE html> 
<html> 
<head> 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" >   </script> 
    <link href="style.css" type="text/css" rel="stylesheet" /> 
</head> 
<body> 
    <div id="test" style="background-color: #FF7300"> 
     <p>Hi</p> 
    </div> 
    <a href="#" id="button">Apply styles</a> 
    <script> 
     $("#button").click(function() { 
      var element = document.getElementById("test"); 
      $("#victim").css(document.defaultView.getComputedStyle(element, null)); 
     }); 
    </script> 
    <div id="victim"> 
     <p>Hi again</p> 
    </div> 
</body> 

//style.css 
#test { 
    border: 3px solid #000000; 
} 

Lo que esto hace es copiar el objeto de estilo computarizada, incluyendo el style.css y el estilo en línea, y la puso al otro div usando css de jQuery()

Espero que no malinterpreten la pregunta y que esto es lo que necesitas

Editar: Algo que olvidé es que usted pidió 'mover' el estilo en lugar de copiarlo. Es muy simple eliminar estilos del div anterior usando jQuery's .removeClass() y usar .attr() para eliminar el atributo de estilo, pero hay que tener en cuenta que si hay reglas de estilo aplicadas al ID del elemento, hay no hay forma de evitar que se apliquen.

0

Así es como lo hago:

var elFrom = document.getElementById('fromID'); 
var computedStyle = document.defaultView.getComputedStyle(elFrom,null); 
$.each(computedStyle,function(key,value) { 
    $('#toID').css(value,$(elFrom).css(value)); 
}); 
Cuestiones relacionadas