2012-09-03 19 views
5

मैं एक jQuery ui कैलेंडर बनाने की कोशिश कर रहा हूं जब 0 दिनांक पर क्लिक किया जाता है, लेकिन कुछ दिन पहले मैं एक समस्या में भाग गया था। मुझे कोड का एक स्निपेट मिला जो माना जाता है, लेकिन जैसा कि मैंने पाया कि यह jQuery कस्टम चयनकर्ताओं का उपयोग करता है। कोड ने मुझे एक त्रुटि दी, इसलिए मैंने कस्टम चयनकर्ताओं में उनके बारे में और जानने के लिए खुदाई शुरू कर दी। अब तक मैं यह पता लगाने में सक्षम नहीं हूं कि मुझे यह अजीब व्यवहार क्यों मिलता है।jQuery कस्टम चयनकर्ता, "अपरिभाषित"

यहाँ एक चित्र को उम्मीद है कि स्पष्ट बातें, मैं और अधिक समझा जाएगा है के बाद यह enter image description here

मैं सांत्वना

$('.ui-datepicker-calendar td a:test(3)') 

में टाइप किया है और जैसा कि आप मैं meta2 और देखो stack2 अपरिभाषित हैं और एक और अजीब चीज, इंडेक्स 2 # डॉक्यूमेंट क्यों लौटाता है, इसमें तत्वों की सरणी का सूचकांक होना चाहिए।

इसके अलावा तत्व (el2) भी सही तत्व नहीं है। एक नजर डालें, मैं फोन

$('.ui-datepicker-calendar td a:test(3)')

इस

कैलेंडर से सभी चयनित तिथियों के लिए माना जाता है, और पहली पाश में, console.log बाहर इस

<td class=" ui-datepicker-week-end " data-handler="selectDay" data-event="click" data-month="8" data-year="2012"><a class="ui-state-default" href="#">1</a></td> 

लेकिन इसके बजाय प्रिंट चाहिए मुझे पूरे दस्तावेज़ में पहला "ए" टैग मिलता है, इस मामले में यह पिछले महीने के लिए एक है (जैसा चित्र में देखा गया है)।

यदि कोई इस स्थिति पर थोड़ा सा प्रकाश डाल सकता है, तो कृपया करें। ओह और एक और बात मैं forgout के बारे में

meta2, अपने इस

[ 
    ':test(argument)', // full selector 
    'test',   // only selector 
    '',    // quotes used 
    'argument'   // parameters 
] 

और मेरे मामले में अपनी अपरिभाषित में फिर से ...

शामिल करने के लिए मैं अपने जावास्क्रिप्ट कोड साझा करेंगे मैं इसे आशा चाहिए

<script> 
    $(function() 
    { 
     $.expr[":"].test = function(el2,index2,meta2,stack2) 
     { 
      debugger; 
      console.log(el2); 
      console.log(index2); 
      console.log(meta2); 
      console.log(stack2); 
     } 
    }) 

    $(function() 
    { 
     function getJsonDate(year, month) 
     { 
      $.getJSON('dates.php?year='+year+'&month='+month, function(data) 
      { 
       var i = 0; 
       for (i = 0; i < data.data.length; i++) 
       { 
        debugger; 
        var myDay = data.data[i]['d']; 
        $('.ui-datepicker-calendar td a:exactly('+data.data[i]['d']+')') 
        .css({color: '#f00'}) 
        .attr('href',data.data[i]['link']) 
        .parent().attr('onclick',''); 
       } 
      }); 
     } 
     $.expr[":"].exactly = function(el, index, meta, stack) 
     { 
      debugger; 
      console.log(el); 
      console.log(index); 
      console.log(meta); 
      console.log(stack); 
      var s = meta[3]; 
      if (!s) return false; 
      return eval("/^" + s + "$/i").test($(el).text()); 
     }; 
     $('#datepicker').datepicker(
     { 
      inline: true, 
      onSelect: function(dateText, inst) 
      { 
       Date.prototype.toString = function() {return isNaN (this) ? 'NaN' : [this.getDate(), this.getMonth(), this.getFullYear()].join('/')} 
       d = new Date(dateText); 
       getJsonDate(d.getFullYear(), d.getMonth()+1); 
      }, 
      onChangeMonthYear: function(year, month, inst) 
      { 
       //alert(year); 
       //alert(month); 
       getJsonDate(year, month); 
      } 
     }); 
    }); 
</script> 
+0

मैं आज सुबह उसी मुद्दे पर भाग गया, जो सुबह 2 बजे बिताया, मेरे लिए मेटा अभी भी अनिर्धारित है। पहले पूरी तरह से काम कर रहा था, अगर आपको कुछ मिल जाएगा तो कृपया मुझे अपडेट रखें। धन्यवाद। –

+0

हैलो @ जकूबकुचर, मैंने इसे काम करने के लिए प्रबंधन नहीं किया था इसलिए मैंने एक कामकाज किया और तत्व को चुना जिसकी मुझे किसी अन्य तरीके की आवश्यकता थी। लेकिन फिर भी मैं वास्तव में जवाब जानने में दिलचस्पी रखता हूं। – Jordashiro

+3

Sizzle jQuery 1.8 में अपडेट किया गया था, जिसके परिणामस्वरूप कस्टम चयनकर्ता निर्माण में महत्वपूर्ण वाक्यविन्यास परिवर्तन हुए। अधिक जानकारी के लिए कृपया तेजस्वी दस्तावेज देखें। https://github.com/jquery/sizzle/wiki/Sizzle- दस्तावेज ऐसा लगता है कि आप jQuery 1.8.1 में अपग्रेड करते हैं, पुराने चयनकर्ता फिर से काम करेंगे। –

उत्तर

6

कम से कम व्याख्या है "jQuery 1.8.0 यह में एक बग है, सुधार के लिए 1.8.1 में नवीनीकृत", लेकिन वह काफी सब कुछ उत्तर नहीं देता।

jQuery 1.8.x में काफी उन्नत "Sizzle" इंजन है, जो कि चयनकर्ताओं के लिए उपयोग करता है। इस तरह के बदलाव के हिस्से के रूप में कस्टम चयनकर्ताओं को बुलाया गया है, लेकिन इसके अलावा कई चयनकर्ताओं को संसाधित करने के तरीके को बदल दिया गया है। नियमों के संसाधित किए जाने वाले आदेश के बारे में विभिन्न धारणाएं अब सत्य नहीं हैं, आदि। यह विभिन्न उपयोग-मामलों में भी काफी तेज है।

यहां तक ​​कि 1.8.1 तक अपग्रेड करते समय भी, आप अभी भी 1.7.2 (पूर्व-1.8.x श्रृंखला में नवीनतम) के तरीके से कुछ अलग दिखते हैं, जो आपके द्वारा प्रदान किए गए उदाहरण को संसाधित करते समय । यह पृष्ठ पर "पहले < > तत्व" के चयन में आप जो देख रहे हैं उसे बताते हैं। यही कहना है: कस्टम चयनकर्ताओं का काम करने की आपकी अपेक्षा यह नहीं है कि वे वास्तव में कैसे काम करते हैं, और यदि आपने लूप को जारी रखने की अनुमति दी है (पहले पुनरावृत्ति पर 'डीबगर' को कॉल करने के बजाय), तो आप देखेंगे कि यह वास्तव में जा रहा है सभी < > तत्व)। संक्षेप में: Sizzle गारंटी नहीं देता है कि विभिन्न नियमों को किस आदेश के लिए बुलाया जा रहा है, केवल परिणाम ही उन सभी से मेल खाता है।

यदि आप निश्चित हैं कि आपका कस्टम नियम अन्य नियमों की तुलना में कम कुशल होगा (शायद क्योंकि आप निश्चित हैं कि अन्य नियम मिलान किए गए तत्वों की संख्या को गंभीर रूप से कम कर सकते हैं), तो आप उन्हें चुनकर पहले चलाने के लिए मजबूर कर सकते हैं, तो .find बुला() तत्वों के केवल उस सबसेट पर, जैसे:

$(".ui-datepicker-calendar").find("td a:test(3)"); 

"ढेर" के रूप में अपरिभाषित जा रहा है, के रूप में केविन बी बताते हैं, हालांकि 1.8.1 अद्यतन पीछे संगतता पुनर्स्थापित करता है, एपीआई बदल गया है, और ऐसा लगता है कि "ढेर" बस छद्म में पारित नहीं किया गया है। यह वास्तव में, बदले गए क्रम के कारण समझ में आता है जिसमें परीक्षण कहा जा सकता है। यही है: जब आप इसे प्राप्त करते हैं तो स्टैक खाली होता है, क्योंकि "< > तत्वों में से कोई भी इस छद्म चयनकर्ता से मेल खाता है" पहला नियम है जो संसाधित हो जाता है। टेस्ट हमेशा आत्मनिर्भर होना चाहिए, इसलिए ढेर वास्तव में बहुत उपयोगी नहीं होगा (केवल भ्रम पैदा कर सकता है)।

तो यदि 1.8.1 पिछड़ा-संगतता बहाल करता है, तो छद्म चयनकर्ता बनाने के लिए आगे-संगत विधि क्या है? जैसा कि आप the documentation for Sizzle's pseudo-selectors में देख सकते हैं, jQuery 1.8 के रूप में छद्म चयनकर्ता बनाने के लिए पसंदीदा विधि "createPseudo" विधि ($ .expr.createPseudo) है, जो "मेटा" तर्क के बजाय बंद करने का विकल्प चुनती है। अपने विशेष उदाहरण के लिए तो, उन्हें ऐसा करने का 'नई' तरीके होगा:

$.expr[":"].test = $.expr.createPseudo(function(tomatch) 
{ 
     return function(el2) 
     { 
      debugger; 
      console.log(el2); // not much else to see here 
     }; 
}) 

जहां "tomatch" करने के लिए तर्क है: परीक्षण (...) चयनकर्ता। जैसा कि आप देख सकते हैं, आप जिन अतिरिक्त तर्कों की तलाश कर रहे थे वे इस नए वाक्यविन्यास में अब आवश्यक नहीं हैं। कुछ थोड़ा और अधिक उपयोगी के लिए के रूप में:

$.expr[":"].exactly = $.expr.createPseudo(function(s) 
{ 
    return function(el) 
    { 
     if(!s) return false; 
     return eval("/^" + s + "$/i").test($(el).text()); 
    }; 
}); 

के इस संस्करण में "वास्तव में" 1.8+ साथ संगत होना चाहिए, और काम करने के वरीय * विधि है।

मुझे लगता है कि jQuery संस्करण/एपीआई में टक्कर के साथ भी, आपके द्वारा प्रदान किया गया कोड अभी भी वही नहीं करेगा जो आप चाहते हैं, क्योंकि डेटपिकर प्लगइन की इच्छा पर पुनर्निर्मित करने के लिए उत्तरदायी है। अभी भी एक संक्षिप्त क्षण है जब आप यह बता सकते हैं कि वांछित तत्व वास्तव में इरादे के रूप में हाइलाइट किए गए हैं, इसलिए चयनकर्ता स्वयं काम कर रहा है।

आपके द्वारा प्रदान किए गए नमूने के आधार पर एक पूर्ण उदाहरण नीचे दिया गया है। आप 1.7.2, 1.8.0, और 1.8.1 के बीच उपयोग किए गए jQuery संस्करण को बदलकर व्यवहार में अंतर देख सकते हैं। संस्करणों में संगतता के लिए, $ .expr.createPseudo के लिए एक परीक्षण छद्म चयनकर्ता फ़ंक्शन असाइनमेंट में जोड़ा गया है। ध्यान दें कि सभी "डीबगर;" स्टेटमेंट्स पर टिप्पणी की गई है, क्योंकि डेटपिकर में सभी डेट लिंक में प्रत्येक पुनरावृत्ति पर ब्रेकपॉइंट होने के कारण, बल्कि थकाऊ हो जाता है, और getJSON कॉल को परीक्षण किया गया है ताकि परीक्षण स्वयं निहित हो सके।

<html> 
<head> 
    <title>jQuery custom selector, "undefined"</title> 
    <!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script> --> 
    <!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.js"></script> --> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.js"></script> 
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.js"></script> 
    <link rel="stylesheet" 
     href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/base/jquery-ui.css" /> 
    <script> 
    $(function() 
    { 
     $.expr[":"].test = $.expr.createPseudo ? 
      $.expr.createPseudo(function(tomatch) 
      { 
       return function(el2) 
       { 
//     debugger; 
        console.log(el2); 
       }; 
      }) : 
      function(el2,index2,meta2,stack2) 
      { 
    //   debugger; 
       console.log(el2); 
       console.log(index2); 
       console.log(meta2); 
       console.log(stack2); 
      }; 
    }) 

    $(function() 
    { 
     function getJsonDate(year, month) 
     { 
      //$.getJSON('dates.php?year='+year+'&month='+month, function(data) 
      //{ 
       var data = {data:[ 
        {d:1,link:"a"}, 
        {d:15,link:"b"}, 
        {d:25,link:"c"} 
       ]}; 
       var i = 0; 
       for (i = 0; i < data.data.length; i++) 
       { 
//     debugger; 
        var myDay = data.data[i]['d']; 
        $('.ui-datepicker-calendar td a:exactly('+data.data[i]['d']+')'). 
         css({color: '#f00'}). 
         attr('href',data.data[i]['link']). 
         parent().attr('onclick',''); 
       } 
      //}); 
     } 

     $.expr[":"].exactly = $.expr.createPseudo ? 
      $.expr.createPseudo(function(s) 
      { 
       return function(el) 
       { 
        if(!s) return false; 
        return eval("/^" + s + "$/i").test($(el).text()); 
       }; 
      }) : 
      function(el, index, meta, stack) 
      { 
//    debugger; 
       console.log(el); 
       console.log(index); 
       console.log(meta); 
       console.log(stack); 
       var s = meta[3]; 
       if (!s) return false; 
       return eval("/^" + s + "$/i").test($(el).text()); 
      }; 

     $('#datepicker').datepicker(
     { 
      inline: true, 
      onSelect: function(dateText, inst) 
      { 
       Date.prototype.toString = function() { 
        return isNaN (this) ? 
         'NaN' : 
         [this.getDate(), this.getMonth(), this.getFullYear()].join('/') 
       } 
       d = new Date(dateText); 
       getJsonDate(d.getFullYear(), d.getMonth()+1); 
      }, 
      onChangeMonthYear: function(year, month, inst) 
      { 
       //alert(year); 
       //alert(month); 
       getJsonDate(year, month); 
       return false; 
      } 
     }); 
    }); 
    </script> 
    <script> 
    (function($){$(function(){ 
     $("<input />"). 
      attr({type:"button", value: "run test selector"}). 
      click(function(){ 
       $(".ui-datepicker-calendar td:test(3) a"); 

       // Or, if you are certain that your test will be less-efficient than an exclusion based 
       // on parents, you could do: 
       // $(".ui-datepicker-calendar").find("td a:test(3)"); 
      }). 
      appendTo("body"); 
    })}(window.jQuery)); 
    </script> 
</head> 
<body> 
    <a href="#ignoreThisLink">.</a> 
    <a href="#ignoreThisToo">.</a> 
    <p> 
     (first, click the input box to cause the datepicker to initialise) 
    </p> 
    <input type="text" id="datepicker" /> 
</body> 
</html> 

मुझे आशा है कि चीजों पर कुछ प्रकाश डालने में मदद मिलेगी।

* मैं कहता हूं कि यह "पसंदीदा" विधि है, लेकिन आप अभी भी "eval" का उपयोग कर रहे हैं। यह बहुत निराश है, क्योंकि यह धीमा है और अप्रत्याशित/आश्चर्यजनक/खतरनाक परिणाम हो सकता है। एक स्ट्रिंग के आधार पर regexes निर्माण करने के लिए एक बेहतर तरीका

return (new RegExp("^" + s + "$", "i")).test($(el).text()); 

होगा हालांकि यहां तक ​​कि इस समस्या नहीं है, के रूप में "एस" रेगुलर एक्सप्रेशन विशेष वर्ण हो सकते हैं। इस विशेष मामले में, हालांकि, एक रेगुलर एक्सप्रेशन भी जरूरत नहीं है, और चीजों के माध्यम से अधिक कुशलता से परीक्षण किया जा सकता:

return String(s).toUpperCase() === $(el).text().toUpperCase(); 

तुम भी बंद में रूपांतरण के लिए, आपको देकर थोड़ा अधिक बचा सकता है का पूरा कार्य:

$.expr[":"].exactly = $.expr.createPseudo(function(s) 
{ 
     if(!s) return function(){ return false; }; 
     s = String(s).toUpperCase(); 

     return function(el) 
     { 
      return (s === $(el).text().toUpperCase()); 
     }; 
}); 
4

jquery ui डेटपिकर की इस तरह की कार्यक्षमता के लिए हुक है। तिथियों को बनाने वाले डीओएम तत्वों को लक्षित करने की कोशिश करने के बजाय, आपको एक को चुनने के व्यवहार से बंधना चाहिए। टिप्पणी के लिए jsFiddle

$('#datepicker').datepicker({ 
    onSelect: function(dateText, inst){ 
     //awesome ajax stuff based on dateText 
    } 
});​ 

संपादित करें: यदि आप एक विशेष तिथि शैली की जरूरत है तो आप इसके पहले यह तैयार की है एक कस्टम वर्ग लगाने से लक्षित करना चाहिए। jsFiddle

$('#datepicker').datepicker({ 
    beforeShowDay: function(date){ 
     return [true, 'date-' + date.getDate() ]; 
    } 
}); 
+0

हाँ, सच है। लेकिन मुझे जरूरत है और मैं हाइलाइटिंग तिथियों के लिए कस्टम jquery चयनकर्ता का उपयोग कर रहा हूं .. उदाहरण के लिए। –

+0

निश्चित रूप से, फिर आप 'preShowDay' कॉलबैक का उपयोग करके तैयार किए जाने से पहले एक कस्टम क्लास को लागू कर सकते हैं, और फिर उस वर्ग को लक्षित करें। नीचे की रेखा, हमेशा jquery UI apis का उपयोग करें, वे व्यापक हैं। – Sinetheta

संबंधित मुद्दे