4

Web 開発は初めてで、index.php にメニューと #content という名前の div があるアプリケーションを開始し、load(); を使用してすべての異なるページを div #content にロードします。div #content にロードされているファイルとともに、それぞれの Java スクリプト ファイルをロードする必要があります。

問題: ここで div に読み込まれる HTML には、いくつかの類似したクラス名と ID があるため、メニュー項目をクリックしてそこで何らかのアクションを実行し、別のメニュー項目に移動して同じアクションを実行すると、スクリプトが取得されます前のメニュー項目が実行されています!

メニュー項目のクリック時に div にスクリプトをロードし、別のメニュー項目のクリック時に以前のスクリプトを削除して、クリックされた現在のメニュー項目から新しいスクリプトをロードするより良い方法はありますか?

div #content をロードするために使用するスクリプト:

$('.nav-button').on('click', function(e){
e.preventDefault();
$('#content').load('../scripts/loader.php');
$('#content').load($(this).attr('href'));
});

sample1.php ページがクリックされた menu-item1 の div に読み込まれます:

<div id='datagrid'>
<input></input>
<input></input>
<input></input>
</div>
<script type='text/javascript' src='scripts/menu-item1/data_script.js'></script>

sample2.php ページがクリックされた menu-item2 の div に読み込まれます:

<div id='datagrid'>
<input></input>
<input></input>
<input></input>
</div>
<script type='text/javascript' src='scripts/menu-item2/data_script.js'></script>
4

2 に答える 2

2

スクリプトをロードする別の方法:

var script = document.createElement("script");
script.type = "text/javascript";
script.src = src;
script.onload = callback_function;

document.getElementsById("#scriptContainer")[0].appendChild(script);

既存のスクリプトの削除について:

スクリプトを特定のコンテナにロードしてみてください。スクリプトを置き換えたい場合は、コンテナのコンテンツをクリアして、新しいスクリプトをロードしてください。

また、requirejs を使用して遅延読み込みを試すこともできます。例はこちら

于 2012-11-01T09:08:38.513 に答える
2

スクリプトが読み込まれて実行されると、自分でコードを整理しない限り、元のスクリプト タグを削除/削除しても、そのコードの残りが残ります。次の点が役立ちます。

  1. js で構造を作成/インポートするときはいつでも、インポート解除/破棄機能をコーディングしたことを確認してください。
  2. .innerHTMLまたはを介し​​て挿入されたスクリプト タグに依存しないでください$().html()- 古いブラウザはそれらを尊重せず、予期しない結果を引き起こす可能性があります - つまり、スクリプト タグが無視されるか、古い Internet Explorer の場合、間違った場所からロードされようとします。
  3. 代わりに、thedev の推奨に従って、スクリプト タグをプログラムで作成します。
  4. ajax された各スクリプトが関連付けられたスクリプト タグを返すようにしたい場合、明らかに#3は注意が必要です。
  5. したがって、ajax リクエストで純粋な HTML を返す代わりに、HTML とロードする必要があるスクリプト パスのリストを含む JSON オブジェクトを返します。
  6. ロードされた各スクリプトが特定の名前のオブジェクトを介して公開されているすべてのメソッドを保持していることを確認すると、次に次のスクリプトをロードするときにこのオブジェクトを削除できます。

以下は例示的なコードです。これを処理するより複雑な(そしてより良い)方法があります(つまり、ウィンドウにオブジェクトを保存することを回避します)。さらに、次のコードは多くの場所で改善される可能性があります。あなたができること、そしてそれについてどのように考えるか。

また、グローバル オブジェクトにオブジェクトを格納する場合は、、または ;) よりも一意の名前を使用する必要があることに注意してくださいwindowonetwothree

マークアップ:

<ul class="menu">
  <li><a href="one.html" data-namespace="one">One Link</a></li>
  <li><a href="two.html" data-namespace="two">Two Link</a></li>
  <li><a href="three.html" data-namespace="three">Three Link</a></li>
</ul>
<div id="content">
  ...
</div>

JavaScript:

/// create a wrapping scope so that our variables can be local
/// to our internal code, but not mess around with the global space.
(function(){

  /// create a remembered lastID var that can store what item was loaded
  var lastID;

  /// an addScripts function that takes a string namespace (can be anything
  /// as long as it obeys usual javascript variable naming rules), and an
  /// array of script URIs.
  var addScripts = function(namespace, scripts){
    var s,i;
    for( i=0; i<scripts.length; i++ ){
      s = $('<script />')
            /// attach our src attribute with the right script path
            .attr('src', scripts[i])
            /// add our namespace as a class to help find script tag later
            .addClass(namespace); 
      /// add to the head of the document
      $('head').append(s);
    }
  }

  /// removeScripts works based on using the namespace we passed
  /// when adding scripts as a classname to find the script tags.
  /// remember removing the tags doesn't remove the executed code.
  var removeScripts = function(namespace){
    /// in order to tidy our code we should include a function
    /// to tidy up.
    if ( window[namespace] && window[namespace].tidyup ) {
      window[namespace].tidyup();
    }
    /// remove the tag to keep the markup neat
    $('script.'+namespace).remove();
  }

  /// a typical click handler applied to the a tags
  $('.menu a').click(function(){

    /// if we have a lastID remove what was before.
    if ( lastID ) {
      removeScripts(lastID);
    }

    /// get our useful info from the link
    var target = $('#content');
    var url = $(this).attr('href');
    /// grab out our "namespace" this will be used to tie the scripts
    /// together with the collection object in the loaded javascript.
    var namespace = $(this).attr('data-namespace');

    /// trigger an ajax request that fetches our json data
    /// from the server.
    $.ajax('loader.php',{dataType:'json',data:{url:url}})
      .done(function(data){
        /// once we have that data, add the html to the page
        target.html( data.html );
        /// and then add the scripts
        addScripts( id, data.scripts || [] );
      });

    /// store the last id so we know what to remove next time
    lastID = id;

  });

})();

ローダー.php:

<?php

  /// create a library of what scripts belong to what page
  $scripts = array(
    'one.html' => array('scripts/js/one.js'),
    'two.html' => array('scripts/js/two.js'),
    'three.html' => array('scripts/js/three.js'),
  );

  /// because `$_GET[url]` can be affected by outside influence
  /// make sure you check it's value before using it.
  switch( ($file = basename($_GET['url'])) ){
    case 'one.html':
    case 'two.html':
    case 'three.html':
      $json = (object) null;
      if ( file_exists($file) ) {
        $json->html = file_get_contents($file);
      }
      if ( isset($scripts[$file]) ) {
        $json->scripts = $scripts[$file];
      }
      header('content-type: application/json');
      /// json_encode should handle escaping all your html correctly
      /// so that it reaches your javascript in one correct piece.
      echo json_encode($json);
    break;
  }

?>

json (上記の php によって返されます):

{
  "html": "<div class=\"random-content\">This can be anything</div>",
  "scripts": ["scripts/js/one.js"]
}

js の例 - つまり (one.js)

/// create our collection object named with the same namespace that
/// appears in the data-namespace attribute in the markup.
window.one = {};

window.one.someMethodThatMightBeUsedByLoadedContent = function(){
  /// this function has been kept specifically as part of the 'one'
  /// object because it needs to be globally accessible by the html
  /// that has been injected into the page. by keeping it as part
  /// of a named object, removing it is rather simple. (see tidyup).
}

window.one.tidyup = function(){
  /// this is the most simplistic way of tidying up a property. Depending
  /// on the complexity of your javascript there are other things you should
  /// keep in mind. If you have any large custom object structures it is best
  /// to traverse these structures key by key and remove each element. Things
  /// to read up on would be 'Javascript memory leaks', 'javascript closures' 
  /// and 'garbage collection'. It is also best to keep in mind you can only
  /// nullify variables i.e. `var abc; abc = null;` -- you can not `delete abc`
  /// this is not a problem for properties i.e. `obj.prop = 123;` and is why
  /// it is best to use them for code you wish to tidy up later.
  delete window.one;
}

$(function(){
  /// trigger off whatever code you need onload
  /// this construction will never been kept by the
  /// javascript runtime as it is entirely anonymous 
  /// so you don't need to be worry about tidying it up.
});

上記のコードは手動で入力されているため、エラーが発生する可能性がありますが、ロードのたびに正しく整理される適切なロード システムを実現する 1 つの方法を示しているはずです。

于 2012-11-01T10:10:34.293 に答える