मैं उस स्क्रिप्ट टैग का संदर्भ कैसे दे सकता हूं जिसने वर्तमान में निष्पादित स्क्रिप्ट लोड की है?


303

मैं उस स्क्रिप्ट तत्व का संदर्भ कैसे दे सकता हूं जिसने वर्तमान में चल रहे जावास्क्रिप्ट को लोड किया था?

यहाँ की स्थिति है। मेरे पास पृष्ठ में उच्च लोड की जा रही "मास्टर" स्क्रिप्ट है, पहली बात HEAD टैग के तहत।

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript" src="scripts.js"></script>

"Script.js" में एक स्क्रिप्ट है जिसे अन्य स्क्रिप्ट्स की ऑन-डिमांड लोडिंग करने में सक्षम होने की आवश्यकता है। सामान्य विधि मेरे लिए काफी काम नहीं करती है क्योंकि मुझे हेड टैग को संदर्भित किए बिना नई स्क्रिप्ट जोड़ने की आवश्यकता है, क्योंकि हेड तत्व समाप्त नहीं हुआ है:

document.getElementsByTagName('head')[0].appendChild(v);

मैं जो करना चाहता हूं वह उस स्क्रिप्ट तत्व का संदर्भ है जिसने वर्तमान स्क्रिप्ट को लोड किया है ताकि मैं उसके बाद अपने नए गतिशील लोड किए गए स्क्रिप्ट टैग को डोम में जोड़ सकूं।

<script type="text/javascript" src="scripts.js"></script>
loaded by scripts.js--><script type="text/javascript" src="new_script1.js"></script>
loaded by scripts.js --><script type="text/javascript" src="new_script2.js"></script>

1
चेतावनी का एक शब्द: डोम लोड करते समय इसे संशोधित करने के कारण आपको IE6 और IE7 में चोट की दुनिया का कारण होगा । आप पृष्ठ लोड होने के बाद उस कोड को चलाना बेहतर समझते हैं।
त्रिपिटक

6
ऐसा लगता है कि यह अब कैनुस पर है: caniuse.com/#feat=document-currentscript
टायलर

जवाबों:


653

वर्तमान स्क्रिप्ट तत्व कैसे प्राप्त करें:

1. उपयोग document.currentScript

document.currentScriptवह <script>तत्व लौटाएगा जिसकी स्क्रिप्ट वर्तमान में संसाधित की जा रही है।

<script>
var me = document.currentScript;
</script>

लाभ

  • सरल और स्पष्ट। विश्वसनीय।
  • स्क्रिप्ट टैग को संशोधित करने की आवश्यकता नहीं है
  • अतुल्यकालिक स्क्रिप्ट के साथ काम करता है ( deferऔर async)
  • स्क्रिप्ट के साथ काम करता है गतिशील रूप से डाला

समस्या

  • पुराने ब्राउज़र और IE में काम नहीं करेगा।
  • मॉड्यूल के साथ काम नहीं करता है <script type="module">

2. आईडी द्वारा स्क्रिप्ट का चयन करें

स्क्रिप्ट को एक आईडी विशेषता देते हुए आप आसानी से उपयोग करके इसे आईडी द्वारा चुन सकते हैं document.getElementById()

<script id="myscript">
var me = document.getElementById('myscript');
</script>

लाभ

  • सरल और स्पष्ट। विश्वसनीय।
  • लगभग सार्वभौमिक रूप से समर्थित
  • अतुल्यकालिक स्क्रिप्ट के साथ काम करता है ( deferऔर async)
  • स्क्रिप्ट के साथ काम करता है गतिशील रूप से डाला

समस्या

  • स्क्रिप्ट टैग में एक कस्टम विशेषता जोड़ने की आवश्यकता है
  • id कुछ ब्राउज़रों के लिए कुछ ब्राउज़रों में स्क्रिप्ट के लिए अजीब व्यवहार का कारण हो सकता है

3. एक data-*विशेषता का उपयोग करके स्क्रिप्ट का चयन करें

स्क्रिप्ट को एक data-*विशेषता देते हुए आप आसानी से इसे भीतर से चुन सकेंगे।

<script data-name="myscript">
var me = document.querySelector('script[data-name="myscript"]');
</script>

पिछले विकल्प की तुलना में इसके कुछ लाभ हैं।

लाभ

  • सरल और स्पष्ट।
  • अतुल्यकालिक स्क्रिप्ट के साथ काम करता है ( deferऔर async)
  • स्क्रिप्ट के साथ काम करता है गतिशील रूप से डाला

समस्या

  • स्क्रिप्ट टैग में एक कस्टम विशेषता जोड़ने की आवश्यकता है
  • HTML5, और querySelector()सभी ब्राउज़रों में अनुरूप नहीं है
  • idविशेषता का उपयोग करने की तुलना में कम व्यापक रूप से समर्थित
  • किनारे के मामलों के <script>साथ मिलेगा id
  • यदि किसी अन्य तत्व में पृष्ठ पर समान डेटा विशेषता और मान है तो भ्रमित हो सकते हैं।

4. src द्वारा स्क्रिप्ट का चयन करें

डेटा विशेषताओं का उपयोग करने के बजाय, आप स्रोत द्वारा स्क्रिप्ट चुनने के लिए चयनकर्ता का उपयोग कर सकते हैं:

<script src="//example.com/embed.js"></script>

एम्बेड में:

var me = document.querySelector('script[src="//example.com/embed.js"]');

लाभ

  • विश्वसनीय
  • अतुल्यकालिक स्क्रिप्ट के साथ काम करता है ( deferऔर async)
  • स्क्रिप्ट के साथ काम करता है गतिशील रूप से डाला
  • कोई कस्टम विशेषताएँ या आईडी की आवश्यकता नहीं है

समस्या

  • स्थानीय स्क्रिप्ट के लिए काम नहीं करता है
  • विभिन्न वातावरणों में समस्याएं पैदा करेगा, जैसे विकास और उत्पादन
  • स्थिर और नाजुक। स्क्रिप्ट फ़ाइल का स्थान बदलने के लिए स्क्रिप्ट को संशोधित करना होगा
  • idविशेषता का उपयोग करने की तुलना में कम व्यापक रूप से समर्थित
  • यदि आप एक ही स्क्रिप्ट को दो बार लोड करते हैं तो समस्याएँ उत्पन्न होंगी

5. जो आप चाहते हैं उसे खोजने के लिए सभी लिपियों पर लूप करें

हम प्रत्येक स्क्रिप्ट तत्व पर भी लूप कर सकते हैं और हम जो चाहें उसका चयन करने के लिए व्यक्तिगत रूप से जाँच सकते हैं:

<script>
var me = null;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
    if( isMe(scripts[i])){
      me = scripts[i];
    }
}
</script>

यह हमें पुराने ब्राउज़रों में दोनों पिछली तकनीकों का उपयोग करने देता है जो querySelector()विशेषताओं के साथ अच्छी तरह से समर्थन नहीं करते हैं । उदाहरण के लिए:

function isMe(scriptElem){
    return scriptElem.getAttribute('src') === "//example.com/embed.js";
}

यह जो भी दृष्टिकोण लिया गया है, उसके लाभों और समस्याओं को विरासत में मिला है, लेकिन इस पर भरोसा नहीं करता है कि querySelector()पुराने ब्राउज़रों में काम करेगा।

6. अंतिम निष्पादित स्क्रिप्ट प्राप्त करें

चूंकि लिपियों को क्रमिक रूप से निष्पादित किया जाता है, अंतिम स्क्रिप्ट तत्व अक्सर वर्तमान में चल रही स्क्रिप्ट होगी:

<script>
var scripts = document.getElementsByTagName( 'script' );
var me = scripts[ scripts.length - 1 ];
</script>

लाभ

  • सरल।
  • लगभग सार्वभौमिक रूप से समर्थित
  • कोई कस्टम विशेषताएँ या आईडी की आवश्यकता नहीं है

समस्या

  • अतुल्यकालिक स्क्रिप्ट ( & ) के साथ काम नहीं करता हैdeferasync
  • गतिशील रूप से सम्मिलित स्क्रिप्ट के साथ काम नहीं करता है

4
इसका उत्तर होना चाहिए।
रॉय नमिर

1
@RoyiNamir से सहमत हैं। यह सबसे अच्छा जवाब है।
हंस

27
धन्यवाद दोस्तों, लेकिन आप जानते हैं कि मैंने स्वीकृत उत्तर के 4 साल बाद जवाब दिया, सही है :)
ब्राइस

5
"document.currentScript" मेरे लिए गतिशील भरी हुई स्क्रिप्ट्स के साथ काम नहीं करता है, नवीनतम क्रोम / फ़ायरफ़ॉक्स में शून्य देता है, "अंतिम निष्पादित स्क्रिप्ट" ठीक काम करता है
xwild

1
काम नहीं करता है जब scriptएक में है templateएक छाया डोम में डाला
supersharp

86

चूंकि स्क्रिप्ट्स को क्रमिक रूप से निष्पादित किया जाता है, वर्तमान में निष्पादित स्क्रिप्ट टैग पृष्ठ पर अंतिम स्क्रिप्ट टैग हमेशा तब तक होता है। तो, स्क्रिप्ट टैग पाने के लिए, आप कर सकते हैं:

var scripts = document.getElementsByTagName( 'script' );
var thisScriptTag = scripts[ scripts.length - 1 ];

3
यह सरल और सुरुचिपूर्ण है। यदि आप जावास्क्रिप्ट को अनपैक करते हैं तो नए Google चार्ट / विज़ुअलाइज़ेशन API में इसका एक उदाहरण है। वे स्क्रिप्ट टैग के भीतर से JSON डेटा लोड करते हैं, देखें: ajax.googleapis.com/ajax/static/modules/gviz/1.0/chart.js
जेसन

1
यह एक महान विचार है, और यह आम तौर पर मेरे लिए काम करता है। लेकिन मुझे यह जोड़ना चाहिए कि ऐसे समय हैं जब मैंने पाया है कि यह एक अलग स्क्रिप्ट का संदर्भ देता है। नहीं यकीन है कि क्यों - कि नीचे ट्रैक करने में सक्षम नहीं किया गया है। नतीजतन, मैं आमतौर पर एक अलग विधि के साथ जाता हूं, उदाहरण के लिए, मैं स्क्रिप्ट फ़ाइल का नाम हार्ड-कोड करता हूं, और उस फ़ाइल नाम के साथ स्क्रिप्ट टैग ढूंढता हूं।
केन स्मिथ

53
एक उदाहरण जो मैं सोच सकता हूं कि गलत परिणाम वापस आ सकता है जब एक स्क्रिप्ट टैग को एसिंक्रोनस रूप से DOM में जोड़ा जाता है।
कॉफी बाइट

9
हां इसके अप्रत्याशित परिणाम हो सकते हैं, इसलिए आप इसके बजाय चयनकर्ता का उपयोग करने का प्रयास कर सकते हैं: $ ('स्क्रिप्ट [src * = "/ mysource.js"]') ???
जेसन सेब्रिंग

7
जब आपके पास पेज लोड होने के बाद स्क्रिप्ट लोड होती है तो यह काम नहीं करता। आपको शायद सही टैग नहीं मिलेगा।
ThemeZ

11

संभवतः सबसे आसान काम यह होगा कि आप अपने टैग को एक idविशेषता दें।


2
हालाँकि आप सही हैं, ऐसे बहुत से मामले हैं जिनमें ओपी का सवाल मान्य है, एक दंपति होगा: 1) जब आप 2 रेंग रहे हों) जब आप एक क्लाइंट के DOM के साथ काम कर रहे हों, और वह बदलने को तैयार न हो
nichochar

10

स्क्रिप्ट को क्रमिक रूप से केवल तभी निष्पादित किया जाता है जब उनके पास "defer" या "async" विशेषता न हो। स्क्रिप्ट टैग के संभावित आईडी / SRC / TITLE विशेषताओं में से एक को जानना उन मामलों में भी काम कर सकता है। इसलिए ग्रेग और जस्टिन दोनों के सुझाव सही हैं।

document.currentScriptWHATWG सूचियों पर एक प्रस्ताव पहले से ही है ।

संपादित करें : फ़ायरफ़ॉक्स> 4 पहले से ही इस बहुत ही उपयोगी संपत्ति को लागू करता है, लेकिन यह आईई 11 में उपलब्ध नहीं है, आखिरी बार मैंने चेक किया था और केवल क्रोम 29 और सफारी 8 में उपलब्ध था।

संपादित करें : किसी ने भी "document.scripts" संग्रह का उल्लेख नहीं किया है, लेकिन मेरा मानना ​​है कि वर्तमान में चल रही स्क्रिप्ट पाने के लिए निम्नलिखित एक अच्छा क्रॉस ब्राउज़र विकल्प हो सकता है:

var me = document.scripts[document.scripts.length -1];

1
यह डॉक्यूमेंट है।
Moritz

9

यहाँ एक पॉलीफ़िल का थोड़ा सा हिस्सा है जो कि document.CurrentScriptमौजूद है और आईडी द्वारा स्क्रिप्ट खोजने के लिए वापस गिरता है।

<script id="uniqueScriptId">
    (function () {
        var thisScript = document.CurrentScript || document.getElementByID('uniqueScriptId');

        // your code referencing thisScript here
    ());
</script>

यदि आप इसे प्रत्येक स्क्रिप्ट टैग के शीर्ष पर शामिल करते हैं, तो मेरा मानना ​​है कि आप लगातार पता कर पाएंगे कि कौन सा स्क्रिप्ट टैग निकाल दिया जा रहा है, और आप एक अतुल्यकालिक कॉलबैक के संदर्भ में स्क्रिप्ट टैग को भी संदर्भित कर पाएंगे।

यदि आप इसे आज़माते हैं, तो अप्रयुक्त है, इसलिए दूसरों के लिए प्रतिक्रिया छोड़ दें।


idविशेषता है अमान्य एक में scriptहालांकि तत्व। इस दृष्टिकोण से किस प्रकार की समस्याएं उत्पन्न हो सकती हैं?
एनआर

1
@nr - नहीं, सभी तत्वों में एक idविशेषता हो सकती है । id, classऔर slotDOM स्तर पर परिभाषित किया जाता है, HTML स्तर पर नहीं। यदि आप HTML में वैश्विक विशेषताओं पर जाते हैं और सूची को स्क्रॉल करते हैं, तो आप पाएंगे "DOM मानक किसी भी नामस्थान में किसी भी तत्व के लिए वर्ग, आईडी और स्लॉट विशेषताओं के लिए उपयोगकर्ता एजेंट आवश्यकताओं को परिभाषित करता है।" इसके बाद "क्लास, आईडी और स्लॉट विशेषताओं को सभी HTML तत्वों पर निर्दिष्ट किया जा सकता है।" DOM कल्पना इसे यहाँ कवर करती है
टीजे क्राउडर

6

यह पेज लोड पर काम करता है और जब स्क्रिप्ट स्क्रिप्ट को जावास्क्रिप्ट के साथ जोड़ा जाता है (उदाहरण के लिए ajax के साथ)

<script id="currentScript">
var $this = document.getElementById("currentScript");
$this.setAttribute("id","");
//...
</script>

3

वर्तमान निष्पादित स्क्रिप्ट ब्लॉक का संदर्भ प्राप्त करने के लिए इन सरल चरणों का पालन करें:

  1. स्क्रिप्ट ब्लॉक के भीतर कुछ यादृच्छिक अद्वितीय स्ट्रिंग रखें (प्रत्येक स्क्रिप्ट ब्लॉक में अद्वितीय / अलग होना चाहिए)
  2. डॉक्यूमेंट का परिणाम ।getElementsByTagName ('स्क्रिप्ट'), उनकी प्रत्येक सामग्री (इनर टेक्स्ट / टेक्स्टकंटेंट प्रॉपर्टी से प्राप्त) से अद्वितीय स्ट्रिंग की तलाश में।

उदाहरण (ABCDE345678 अद्वितीय आईडी है) :

<script type="text/javascript">
var A=document.getElementsByTagName('script'),i=count(A),thi$;
for(;i;thi$=A[--i])
  if((thi$.innerText||thi$.textContent).indexOf('ABCDE345678'))break;
// Now thi$ is refer to current script block
</script>

btw, आपके मामले के लिए, आप किसी अन्य स्क्रिप्ट को शामिल करने के लिए बस पुराने ज़माने के दस्तावेज का उपयोग कर सकते हैं। जैसा कि आपने उल्लेख किया है कि डोम अभी तक प्रदान नहीं किया गया है, आप इस तथ्य से लाभ उठा सकते हैं कि ब्राउज़र हमेशा रैखिक अनुक्रम में स्क्रिप्ट को निष्पादित करता है (बाद में रेंडर किए गए एक को छोड़कर), इसलिए आपके बाकी दस्तावेज़ अभी भी "अस्तित्व में नहीं हैं"। कुछ भी जो आप डॉक्यूमेंट के माध्यम से लिखते हैं। राइट () कॉलर स्क्रिप्ट के ठीक बाद रखा जाएगा।

मूल HTML पृष्ठ का उदाहरण :

<!doctype html>
<html><head>
<script src="script.js"></script>
<script src="otherscript.js"></script>
<body>anything</body></html>

Script.js की सामग्री :

document.write('<script src="inserted.js"></script>');

प्रस्तुत करने के बाद, DOM संरचना बन जाएगी:

HEAD
  SCRIPT script.js
  SCRIPT inserted.js
  SCRIPT otherscript.js
BODY

यह केवल इनलाइन स्क्रिप्ट के लिए काम करता है, बाहरी स्क्रिप्ट के लिए नहीं। उत्तरार्द्ध मामले में सभी गुण इनरटेक्स्ट, टेक्स्ट और टेक्स्टकॉन्टेंट खाली हैं।
जोस डे जोंग

3

Async और आस्थगित लिपियों से निपटने के लिए एक दृष्टिकोण है ऑनलोड हैंडलर का लाभ उठाने के लिए- सभी स्क्रिप्ट टैग के लिए एक ऑनलोड हैंडलर सेट करना और पहला जो निष्पादित होता है वह आपका होना चाहिए।

function getCurrentScript(callback) {
  if (document.currentScript) {
    callback(document.currentScript);
    return;
  }
  var scripts = document.scripts;
  function onLoad() {
    for (var i = 0; i < scripts.length; ++i) {
      scripts[i].removeEventListener('load', onLoad, false);
    }
    callback(event.target);
  }
  for (var i = 0; i < scripts.length; ++i) {
    scripts[i].addEventListener('load', onLoad, false);
  }
}

getCurrentScript(function(currentScript) {
  window.console.log(currentScript.src);
});

3

स्क्रिप्ट प्राप्त करने के लिए, जो वर्तमान में आपके द्वारा उपयोग की जाने वाली स्क्रिप्ट को लोड करता है

var thisScript = document.currentScript;

आपको अपनी स्क्रिप्ट की शुरुआत में एक संदर्भ रखना होगा, इसलिए आप बाद में कॉल कर सकते हैं

var url = thisScript.src

2

इस एल्गोरिथ्म पर विचार करें। जब आपकी स्क्रिप्ट लोड होती है (यदि कई समान स्क्रिप्ट हैं), document.scripts के माध्यम से देखें, पहली स्क्रिप्ट को सही "src" विशेषता के साथ खोजें, और इसे सहेजें और इसे डेटा-विशेषता या अद्वितीय क्लासनेम के साथ 'विज़िट' के रूप में चिह्नित करें।

जब अगली स्क्रिप्ट लोड होती है, तो document.scripts के माध्यम से फिर से स्कैन करें, पहले से चिह्नित किसी भी स्क्रिप्ट पर गुजरते हुए। उस स्क्रिप्ट की पहली परिकल्पित मिसाल लीजिए।

यह मानता है कि समान लिपियों की संभावना उस क्रम में निष्पादित होगी जिसमें वे लोड किए गए हैं, सिर से शरीर तक, ऊपर से नीचे, सिंक्रोनस से एसिंक्रोनस तक।

(function () {
  var scripts = document.scripts;

  // Scan for this data-* attribute
  var dataAttr = 'data-your-attribute-here';

  var i = 0;
  var script;
  while (i < scripts.length) {
    script = scripts[i];
    if (/your_script_here\.js/i.test(script.src)
        && !script.hasAttribute(dataAttr)) {

        // A good match will break the loop before
        // script is set to null.
        break;
    }

    // If we exit the loop through a while condition failure,
    // a check for null will reveal there are no matches.
    script = null;
    ++i;
  }

  /**
   * This specific your_script_here.js script tag.
   * @type {Element|Node}
   */
  var yourScriptVariable = null;

  // Mark the script an pass it on.
  if (script) {
    script.setAttribute(dataAttr, '');
    yourScriptVariable = script;
  }
})();

यह पहली मिलान स्क्रिप्ट के लिए सभी स्क्रिप्ट के माध्यम से स्कैन करेगा जो विशेष विशेषता के साथ चिह्नित नहीं है।

फिर उस नोड को चिह्नित करें, यदि मिला, तो डेटा-विशेषता के साथ बाद के स्कैन इसे नहीं चुनेंगे। यह ग्राफ ट्रैवर्सल बीएफएस और डीएफएस एल्गोरिदम के समान है, जहां रीविज़िट को रोकने के लिए नोड्स को 'विज़िट' के रूप में चिह्नित किया जा सकता है।


ढेर अतिप्रवाह में आपका स्वागत है। क्या आप एल्गोरिथ्म के साथ कुछ कोड शामिल करने की परवाह करेंगे?
Gary99

थार तुम जाओ, @ Gary99
LSOJ

0

मुझे यह मिल गया है, जो FF3, IE6 & 7 में काम कर रहा है। ऑन-लोडेड स्क्रिप्ट की विधियाँ पृष्ठ लोड पूरा होने तक उपलब्ध नहीं हैं, लेकिन यह अभी भी बहुत उपयोगी है।

//handle on-demand loading of javascripts
makescript = function(url){
    var v = document.createElement('script');
    v.src=url;
    v.type='text/javascript';

    //insertAfter. Get last <script> tag in DOM
    d=document.getElementsByTagName('script')[(document.getElementsByTagName('script').length-1)];
    d.parentNode.insertBefore( v, d.nextSibling );
}

0

यदि आप स्क्रिप्ट का फ़ाइल नाम मान सकते हैं, तो आप इसे पा सकते हैं। मैंने अभी तक फ़ायरफ़ॉक्स में केवल निम्न फ़ंक्शन का परीक्षण किया है।

  function findMe(tag, attr, file) {
    var tags = document.getElementsByTagName(tag);
    var r = new RegExp(file + '$');
    for (var i = 0;i < tags.length;i++) {
      if (r.exec(tags[i][attr])) {
        return tags[i][attr];
      }
    }
  };
  var element = findMe('script', 'src', 'scripts.js');

1
बहुत पुराना है। यह क्वेरीसेलेक्टर, एक सरल ऑन्लाइनर के साथ किया जा सकता है!
फेबियन वॉन एलर्ट्स

-1

मैंने निम्नलिखित कोड को सबसे अधिक सुसंगत, निष्पादक और सरल पाया है।

var scripts = document.getElementsByTagName('script');
var thisScript = null;
var i = scripts.length;
while (i--) {
  if (scripts[i].src && (scripts[i].src.indexOf('yourscript.js') !== -1)) {
    thisScript = scripts[i];
    break;
  }
}
console.log(thisScript);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.