2014-12-15 11 views
8

के बाहर एक jQuery क्लोन का उपयोग करना मैं एक छोटी परियोजना पर काम कर रहा हूं जहां मैं jQuery .clone() विधि का उपयोग कर रहा हूं। इसके साथ Pitfall इसका उपयोग HTML पर कर रहा है जिसमें अद्वितीय पहचानकर्ता हैं। तो मैं मूल अद्वितीय तत्वों की शैली गुणों को ढूंढने के लिए getComputedStyle को लागू करने के लिए चला गया, ताकि इसे क्लोन पर कॉपी किया जा सके और बाद में एक नई आईडी दें (हां, यह प्रदर्शन के मुद्दों को दे सकता है लेकिन यह प्रयोगात्मक है)।डीओएम

jQuery spec के अनुसार, क्लोनिंग के बाद ऐसा करने से पहले, लेकिन संलग्न होने से पहले मैन्युअल रूप से डोम के बाहर हो जाएगा (इसलिए कोई आईडी 'उल्लंघन' नहीं होगा)। लेकिन जब मैंने वस्तु को क्लोन करने के बाद तत्वों की शैली गुणों को खोजने का प्रयास किया, तो मैंने ब्राउज़रों में कुछ अजीब व्यवहार देखा। यह करने से पहले, सभी ब्राउज़रों एक ही मान लेकिन बाद क्लोन किया जा रहा:

  • फ़ायरफ़ॉक्स - लापरवाह, और दिलचस्प क्लोन की गणना शैली अभिकलन डेटा (पिक्सेल में) वास्तविक सीएसएस मूल्य के बजाय है।

  • आईई - काम करने लगता है लेकिन मूल्य जरूरी नहीं है।

  • क्रोम - गणना नहीं करता है।

http://codepen.io/anon/pen/zxqmNK?editors=011

var elements = []; 
var objects = []; 

$('body').find('[id]').each(function() { 
    elements.push(this); 
}); 

$('body').clone().find('[id]').each(function() { 
    objects.push(this); 
}); 

$.each(elements, function(key, element) { 
    var current = window.getComputedStyle(element, null).getPropertyValue('width'); 
    $('#log').append('<p>' + element.id + ': ' + current + '</p>'); 
}); 

$('#log').append('</br>'); 

$.each(objects, function(count, object) { 
    var current = window.getComputedStyle(object, null).getPropertyValue('width'); 
    $('#log').append('<p>' + object.id + ': ' + current + '</p>'); 
}); 

किसी को पता है अगर यह एक बग है या इसी तरह के व्यवहार से पहले देखा गया है: यहाँ एक उदाहरण है? वेब-वार पर जाने के लिए बहुत कुछ नहीं है (यहां तक ​​कि स्टैक ओवरफ्लो भी नहीं)। किसी भी अंतर्दृष्टि के लिए अग्रिम धन्यवाद।

संपादित करें - कुछ और परीक्षण किया और ऐसा लगता है कि आईई क्रोम के समान व्यवहार करता है। केवल कुछ भी वापस करने की बजाय, सब कुछ 'ऑटो' पर सेट है। यदि क्लोन ऑब्जेक्ट्स की शैली .css() का उपयोग करके एक्सेस की जाती है, तो सभी मान 0px (पृष्ठभूमि जैसे गुणों सहित) लौटाते हैं। लगता है कि मोज़िला क्लोन ऑब्जेक्ट का इलाज करता है जैसे कि किसी भी शैली को बिल्कुल लागू किया गया है।

+2

नहीं एक सीधा जवाब है, लेकिन तुम क्यों 'getComputedStyle' इतना साथ काम करना चाहते हैं? क्या सीएसएस शैलियों को अपना रास्ता खोजने के बजाए कक्षाओं का उपयोग करके अपने तत्वों को स्टाइल करने के लिए यह आसान और तरीका अधिक अनुमानित नहीं होगा? – Matijs

+1

मुझे लगता है [यह आपकी मदद कर सकता है] (http://stackoverflow.com/q/18706243/473016) – anpsmn

+0

धन्यवाद, anpsmn। मुझे विश्वास नहीं है कि मुझे वह नहीं मिला। मैंने वास्तव में फ़ेलिक्स क्लिंग के सुझाव देने का फैसला किया था (मूल वस्तुओं से प्रतिलिपि शैली)। यद्यपि मोज़िला को संभालने का तरीका यह बहुत बढ़िया होगा अगर यह क्रॉस ब्राउज़र उपलब्ध था। मतिज, आप निश्चित रूप से सही हैं लेकिन इसे निकाला गया कोड एक छोटी प्लगइन (आवर्धक) के रूप में है, जहां मैं लोगों को अपनी फ़ाइल संरचना को बदलने के लिए मजबूर नहीं करना चाहता हूं। मैं निश्चित रूप से कक्षाओं का उपयोग करने की सिफारिश करेंगे। जवाब के लिए चीयर्स। – Shikkediel

उत्तर

1

पहले दृष्टिकोण

यहाँ कैसे मैं इसे शुरू में हल ... इलाज मोज़िला अलग ढंग से आकर्षक है, लेकिन उसमें सूँघने तो हम चारों ओर क्लोन की शैली उपयोग करने में सक्षम नहीं किया जा रहा काम करेंगे ब्राउज़र की आवश्यकता होगी।

वस्तुओं में अद्वितीय पहचानकर्ता है कि दो सरणियों का निर्माण - पहले एक तत्व शामिल होंगे से शैली की नकल करने के लिए और दूसरा क्लोन तत्व है जो करने के लिए शैली स्थानांतरित कर दिया जाएगा धारण करने के लिए:

var individual = [], singular = []; 

$('.target').find('[id]').each(function() { 

    individual.push(this); 
}) 
.end().clone().find('[id]').each(function() { 

    singular.push(this); 
}); 

अब ,

$.each(individual, function(key) { 

    var tag = this.id, 
    styles = window.getComputedStyle(this, null), 
    element = singular[key]; 

    $.each(styles, function() { 

     var value = styles.getPropertyValue(this); 
     $(element).css(this, value); 
    }); 

    $(element).attr('id', tag + '-cloned'); 
}); 

क्लोन आइटम इस के बाद डाला जाता है: उसके बाद वर्तमान पहचानकर्ता के नाम कुछ अद्वितीय करने के लिए बदल जाता है - गुण और उनके मान ऑब्जेक्ट की श्रेणी है कि क्लोन करने के लिए डोम के अंदर संग्रहित कर रहे थे से नकल कर रहे हैं तो कोई डबल पहचानकर्ता कभी मौजूद नहीं हैं। ध्यान दें कि यह कई स्टाइल गुणों का उत्पादन कर सकता है (उदाहरण के लिए फ़ायरफ़ॉक्स में प्रत्येक ऑब्जेक्ट के लिए 220)।

Demo

var individual = [], singular = []; 

$('.target').find('[id]').each(function() { 

    individual.push(this); 
}) 
.end().clone().find('[id]').each(function() { 

    singular.push(this); 
}) 
.end().queue(function() { 

    transFigure(); 
    $(this).dequeue(); 
}) 
.appendTo('body'); 

function transFigure() { 

$.each(individual, function(key) { 

    var tag = this.id, 
    styles = window.getComputedStyle(this, null), 
    element = singular[key]; 

    $.each(styles, function() { 

     var value = styles.getPropertyValue(this); 
     $(element).css(this, value); 
    }); 

    $(element).attr('id', tag + '-cloned'); 
}); 
} 

++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++

दूसरा दृष्टिकोण

हालांकि उपर्युक्त काम ठीक है, यह बहुत ही कुशल नहीं है और पृष्ठ का आकार बदलने के मूल्य अलग-अलग हो सकते हैं। इसलिए मुझे आने के बाद और फिर जावास्क्रिप्ट के cssRules पर कुछ खुदाई करने के बाद एक बेहतर समाधान मिला है। इसके साथ आप वास्तव में सभी स्टाइल शीट्स को सीधे एक्सेस कर सकते हैं!

नीचे एक कलम है जो प्रक्रिया को समझाने की कोशिश करती है लेकिन स्टाइलशीट के अंदर cssText के खिलाफ क्लोन के भीतर अद्वितीय पहचानकर्ता मिलान करने के लिए नीचे आता है (.test के साथ)। फिर id बदलना और उसे सरणी में संग्रहीत करना, इसके बाद इसे बाद में स्टाइलशीट में डाला/जोड़ा जाना चाहिए।

Pen

एक अधिक कुशल दृष्टिकोण इसके अलावा

(कोई सभी मूलभूत मूल्यों के हस्तांतरण), वास्तविक सीएसएस परिकलित मान के बजाय सभी ब्राउज़रों के लिए नकल की जाती है। और img, p जैसे किसी भी डेरिवेटिव और इसमें भी शामिल किया जा सकता है। यह @rules की प्रतिलिपि बनाता है और इस तरह प्रतिक्रिया को बरकरार रखता है।

यह का सार:

var singular = [], rules = []; 

$('#target').clone().find('[id]').each(function() { 

    singular.push(this); 
}); 

var sheet = document.styleSheets[0], 
styles = sheet.cssRules; 

$.each(singular, function() { 

    var selector = '#' + this.id, 
    pattern = new RegExp(selector + '(:| |,)'); 

    $.each(styles, function() { 

     var string = this.cssText; 

     if (pattern.test(string)) { 
     var rule = string.replace(selector, selector + '-duplicate'); 
     rules.push(rule); 
     } 
    }); 
}); 

$.each(rules, function() { 

    var index = styles.length; 
    sheet.insertRule(this, index); 
}); 

इस क्लोन के बाद, डोम के लिए डाला जा सकता है सब एकमात्र पहचान और पूर्ण शैली के साथ लागू किया जा रहा। ध्यान दें कि उपर्युक्त उदाहरण में यह वास्तव में कोड को cssRules का उपयोग करने के लिए जितना संभव हो सके पठनीय रखने के लिए नहीं किया गया है। छवि को अलग-अलग id के साथ पहले मार्कअप के अंदर रखा गया है - जो कॉपी किए गए स्टाइल नियमों से मेल खाता है।