2017-02-05 16 views
0

私はjQueryで絶対に始まっています。私のアプリ用のコードをいくつか書いて、それを.jsファイルに入れました。jQuery - コードの繰り返し

jQueryでコードの繰り返しを避けるにはどうすればよいですか?私の.jsコード(1つの巨大な.jsファイル、より小さいまたはまっすぐなhtmlソース)をどこに保存する必要がありますか?

これは私の.jsファイルです:

$(document).ready(function() { 
    $("label[for='id_category1'], #id_category1, label[for='id_subcategory1'],#id_subcategory1 ").hide(); 
    $('select[name=subcategory]').empty(); 
    $('select[name=subcategory]').prepend('<option value="Not selected" selected disabled>Select Category...</option>'); 
    $('select[name=subcategory1]').empty(); 
    $('select[name=subcategory1]').prepend('<option value="Not selected" selected disabled>Select Category...</option>'); 
    // called when category field changes from initial value 
    $('#id_group').change(function() { 
     var $this = $(this); 
     if ($this.find('option:selected').attr('value') == 'premium') { 
      $("label[for='id_category1'], #id_category1").show(); 
      $("label[for='id_subcategory1'], #id_subcategory1").show(); 
     } else { 
      $("label[for='id_category1'], #id_category1").hide(); 
      $("label[for='id_subcategory1'], #id_subcategory1").hide(); 
     } 
    }) 


    $('#id_category').change(function() { 
     var $this = $(this); 
     if ($this.find('option:selected').index() !== 0) { 
      category_id = $('select[name=category]').val(); 
      request_url = '/get_subcategory/' + category_id + '/'; 
      $.ajax({ 
       url: request_url, 
       type: "GET", 
       success: function(data) { 
        $('select[name=subcategory]').empty(); 
        $.each(data, function(key, value) { 
         $('select[name=subcategory]').append('<option value="' + key + '">' + value + '</option>'); 
        }); 
       } 
      }) 
     } 
    }) 
    $('#id_category1').change(function() { 
     var $this = $(this); 
     if ($this.find('option:selected').index() !== 0) { 
      category_id = $('select[name=category1]').val(); 
      request_url = '/get_subcategory/' + category_id + '/'; 
      $.ajax({ 
       url: request_url, 
       type: "GET", 
       success: function(data) { 
        $('select[name=subcategory1]').empty(); 
        $.each(data, function(key, value) { 
         $('select[name=subcategory1]').append('<option value="' + key + '">' + value + '</option>'); 
        }); 
       } 
      }) 
     } 
    }) 
    $("label[for='id_keywords']").html("Keywords 0/100"); 
    $('#id_keywords').keyup(function() { 
     var charsno = $(this).val().length; 
     $("label[for='id_keywords']").html("Keywords (" + charsno + "/100)"); 
    }); 
    $("label[for='id_description']").html("Description 0/250"); 
    $('#id_description').keyup(function() { 
     var charsno = $(this).val().length; 
     $("label[for='id_description']").html("Description (" + charsno + "/2500)"); 
    }); 
}); 

は、初心者への手がかりをいただき、ありがとうございます。

+1

あなたが求めているものは意見に基づいています。 1つの大きなファイルを使用するか、いくつかの小さなファイルを使用するかどうかは、プロジェクトとあなたによって異なり、[議論されている](http://stackoverflow.com/questions/15236767/one-big-javascript-file-or複数の小さなファイル)、それは依然として意見の問題ですが、HTTP/2では複数のリクエストがより効率的になりました。ただし、CSSを.cssファイルに、javascriptを.jsファイルに、HTMLをHTMLと区別して保存する必要があります。コードの繰り返しについては、よりスマートなセレクタと多くの変数が多く解決します。 – adeneo

+0

あなたは既に私が何と答えているかを述べています:) – Datadimension

答えて

0

いつもHTMLからjavascriptを分離します。

別々の機能に応じて別々のjavascriptファイルを分離して読み込みます。

次に、MVCタイプのアーキテクチャに分割してください。私はjavascriptファイルの長さが2000行で、編集やデバッグには扱いにくい場所にいました。

いつもクラスを試してみてください。例えば次に

var view; 
var model; 
var ctrl; 

/** - js_include_mvc.js 
* as per: 
* http://stackoverflow.com/questions/15192722/javascript-extending-class 
* provides the bare minimum facility to instantiate MVC objects if the base mvc classes are not subclassed 
* this ensures there is always js mvc 
* 
*/ 
Ctrl.inherits(BaseCtrl); 
function Ctrl(args) { 
    BaseCtrl.apply(this, arguments); 
    Ctrl.prototype.boot = function() { 

    } 
} 

View.inherits(BaseView); 
function View(args) { 
    BaseView.apply(this, arguments); 
    View.prototype.boot = function() { 

    } 
} 

Model.inherits(BaseModel); 
function Model(args) { 
    BaseModel.apply(this, arguments); 
    Model.prototype.boot = function() { 

    } 
} 

Classアーキテクチャは、JavaScriptで擬似しかしある

function BaseView() { 
    BaseView.prototype.somemethod = function() { 
     //some functionality here 
     return "I am a View"; 
    } 
} 

そして最後にグローバルページのスクリプトでそれを呼び出す:

var view=new BaseView(); 
view.somemethod(); 

出力:

「私はビューです」

ここで私はいつもここで再利用されているコードを入れていますが、BaseViewクラスはアプリケーションに応じてさらに拡張できます。だからBaseViewは私のすべてのアプリケーションのメインリポジトリとして使われており、要件に応じて拡張しています。

+0

私の.jsファイルから機能を分離するにはどうしたらいいですか?コードには2つの部分があります。上部は私のフォームの操作選択フィールドのためのもので、下部は同じフォームのラベルを表示するためのものです。私はそれを分けるべきですか? 1ページに2つ以上の.jsファイルを使用することは可能ですか?今のところ私はhtmlファイルにもう1つのjQueryスクリプトを持っています。これはフォームを送信した後にサイトをリダイレクトするためのものです。 – jundymek

-1

2つのAJAXリクエストを組み合わせることが1つです。 changeハンドラには複数のセレクタを使用できます。 $('#id_category', '#id_category1').change(etc...のようなものです。どのリクエストを処理しているのかを正確にターゲットにする方法を見つけることができると確信しています。 the docsと同様に、他の機能にも複数のセレクタを使用できます。

ファイルが比較的短い(〜100〜200行)場合は、すべてをすべて1か所に保存しても問題ないと思います。それ以外の場合は、関数をファイルに明確に分離し、必要に応じてrequireを指定します。これにはrequireJSを使用することができます。

+0

が必要ですか? - 答えのためのコードと間違ったプログラミング言語はありません! – Datadimension

+0

これはPHPのネイティブ(? - 私はかなりphpに新)ですが、あなたは同様にそれを行うために外部のJSライブラリやツールを使用することができます。 [Require JS](http://requirejs.org)がその一例です。その他には[webpack](https://webpack.js.org)、[ブラウザー化](http://browserify.org/)などがあります。 – aberkow

+0

質問は「jQueryでコードの繰り返しを避ける」で、PHPではありません – Datadimension

0

私のコードのコメントの一部が書き換えを必要とするが、私のAjaxのクラスはこのように書き:

if (SERVER_INTERFACES == undefined) { 
    var SERVER_INTERFACES = {};//global server array required for named multiple servers and asynch data callbacks 
} 

/** Ajax_js - communicates with the server to retreive data 
* 
* @param String newName is the name this class can reference for things like callbacks 
* @param Strin newUrl 
* @param String newNamedServer is the resource url defined as a php ajax server class 
* @returns {Ajax} 
*/ 
function Ajax_m(newName, newUrl, newNamedServer) { 
    this.namedServer = newNamedServer; 
    this.interface_name = newName; 
    this.url = newUrl; 
    this.server_data; //allows a query to be given an id and the result data stored and accessible without having to manipulate into method arguments which might require data changes 
    this.server_data = new Array(); //allows a query to be given an id and the result data stored and accessible without having to manipulate into method arguments which might require data changes 
    this.request_index = 0; 
    this.multiqueryindex = 0; 
    this.multiqueryctrl = new Array(); 
    this.dataType = "json"; 
    this.reqType = "post"; 
    SERVER_INTERFACES[this.interface_name] = this; 
    Ajax_m.prototype.request = function (requestobj, callback, optargs) { 
    optargs = model.array_defaults(optargs, {runtagvals: {}}); 
    if (optargs.id == undefined) { 
     this.request_index++; 
    } else { 
     this.request_index = optargs.id; 
    } 
    var request_id = this.request_index; 
    if (typeof requestobj == "string") { 
     //legacy was the requestobj as a string which is set to request and defaults assumed 
     //attempt to parse ajaxRequestSubType as first 'word' 
     var clauseend = requestobj.indexOf(" "); 
     var ajaxRequestSubType = requestobj.substr(0, clauseend); 
     requestobj = {ajaxRequestSubType: ajaxRequestSubType, request: requestobj, callback: callback, request_id: request_id}; 

    } else { 
     //for legacy if callback and id are defined they are added but if in requestobj they will be overridden 
     var args = {callback: callback, request_id: request_id}; 
     for (var r in requestobj) { 
     args[r] = requestobj[r]; 
     } 
     requestobj = args; 
    } 

    //ensure default settings 
    var requestbuild = model.array_defaults(
      requestobj, 
      { 
       request: null, 
       callback: "", 
       errorCallback: null, 
       request_id: null, 
       interface_name: this.interface_name, 
       responsedata: null, 
       multirequestid: null, 
       ajaxRequestSubType: "", 
       ajaxRequestType: "database", //default to use database cfg definitions of site 
       ismultiparent: false, 
       _method: "PATCH"//for laravel5 
      } 
    ); 

    requestbuild.request = model.runtagreplace(requestbuild.request, optargs.runtagvals); 

    this.server_data[request_id] = requestbuild; 
    //debug in chrome as firebug fucks up badly with switch control 
    switch (requestbuild.ajaxRequestSubType) { 
     //control processes so no actual ajax requests are required 
     case "multirequest_parent": 
     case "multilrequest_submit": 
     break; 
     default: 
     this.server_data[request_id].ajax = $.ajax({ 
      headers: { 
      'X-CSRF-TOKEN': laravelCSRF//this is a constant from php JSCONSTANTS 
      }, 
      url: this.url, 
      type: this.reqType, 
      data: requestbuild, 
      dataType: this.dataType, 
      success: function (server_response) { 

      var requestobj = SERVER_INTERFACES[server_response.interface_name]; //.server_data[request_id]; 
      if (requestobj.server_data[request_id] != undefined) {//check existence - a reset might have been requested since query sent 
       requestobj.setRequestResult(server_response.request_id, server_response.data); 
       //check through request types to eventual detect a simple callback from client object 
       switch (server_response.ajaxRequestSubType) { 
       case "select": 
       case "call": 
        if (server_response.flag_multiRequestChild) { 
        var parentinterface_name = requestobj.interface_name; 
        var parentinterface_id = server_response.multirequest_parent; 
        var multiobj = 
          SERVER_INTERFACES[parentinterface_name]. 
          server_data[parentinterface_id]; 
        multiobj.request_returned++; 
        if (multiobj.request_returned == multiobj.request_total) { 
         requestobj.multiRequestFinish(requestobj.server_data[request_id].multirequest_parent); 
        } 
        } else if (server_response.callback != "") { 
        eval(server_response.callback + "(" + server_response.request_id + ",'" + requestobj.interface_name + "')"); 
        } 
        break; 
       case "submit": 
        if (!server_response.ismultipart) { 
        if (server_response.callback != "") { 
         eval(server_response.callback + "(" + server_response.request_id + ")"); 
        } 
        } else { 
        var multiobj = SERVER_INTERFACES[server_response.interface_name].server_data[requestobj.server_data[request_id].multisubmit_parent]; 
        multiobj.submit_returned++; 
        if (multiobj.submit_returned == multiobj.submit_total) { 
         requestobj.multiSubmitFinish(requestobj.server_data[request_id].multisubmit_parent); 
        } 
        } 
        break; 
       case "jscsv": 
        var downloadobj = SERVER_INTERFACES[server_response.interface_name].server_data[request_id]; 
        requestobj.downloadrun(downloadobj); 
        break; 

       default://need failover as cannot determine what to do 
        break; 
       } 
      } else { 
       var faildata = "error"; 
      } 
      }, 
      error: function (server_response) { 
      //parse unhelpful error 'data' to relocate correct ajax request object 
      var errordata = this.data.split("&"); 
      var intefacename; 
      var requestid; 
      var errorobj = {isajaxerror: true}; 
      for (var i in errordata) { 
       var keyval = errordata[i].split("="); 
       errorobj[keyval[0]] = keyval[1]; 
       if (errordata[i].indexOf("request_id=") != -1) { 
       requestid = errordata[i].substr(errordata[i].indexOf("=") + 1); 
       } 
       if (errordata[i].indexOf("interface_name=") != -1) { 
       interfacename = errordata[i].substr(errordata[i].indexOf("=") + 1); 
       } 
      } 
      var parentobj = SERVER_INTERFACES[interfacename]; 
      var requestobj = parentobj.server_data[requestid]; 
      //new object required as out of scope 

      errorobj["responseText"] = server_response.responseText; 
      parentobj.setRequestResult(errorobj["request_id"], errorobj); 
      eval(errorobj["callback"] + "(" + errorobj["request_id"] + ")"); 
      } 
     }); 
     break; 
    } 
    return request_id; 
    } 

    /* 
    * handles ajax where data is not expected back such as an insert statement or email send 
    * but can expect a response message such as 'ok' or an error message 
    */ 
    Ajax_m.prototype.submit = function (type, submitdata, callback) { 
    this.request({ajaxRequestSubType: "submit", type: type, submitdata: submitdata, ismultipart: false, callback: callback}); 
    } 

    /* 
    * 'multiSubmit' handles ajax where data is not expected back such as an insert statement or email send 
    * but can expect a response message such as 'ok' or an error message 
    * EXAMPLE 
    var multisub = [ 
    { 
    type: "update", 
    data: { 
    table: "[xondbs1].stats.dbo.a_ppuser", 
    values: {'email': 'tim'}, 
    matchfield: 'keyval', matchvalue: 'Q00010017' 
    } 
    }, 
    { 
    type: "update", 
    data: { 
    table: "[xondbs1].stats.dbo.a_ppuser", 
    values: {'email': 'tim'}, 
    matchfield: 'keyval', matchvalue: 'Q00010017' 
    } 
    } 
    ]; 
    ajaxdbobj.multiSubmit(multisub, "callbackfunctionname"); 
    */ 
    Ajax_m.prototype.multiSubmit = function (submitobject, callback) { 
    var parent_request_id = this.request({ajaxRequestSubType: "multisubmit_parent", submit_total: count(submitobject), submit_returned: 0, id_list: [], submit: {}, response: {}, callback: callback}); 
    for (var s in submitobject) { 
     var child_request_id = this.request({ 
     ajaxRequestSubType: "submit", 
     multisubmit_parent: parent_request_id, 
     ismultipart: true, 
     type: submitobject[s].type, 
     submitdata: submitobject[s].data 
     }); 
     this.server_data[parent_request_id].id_list[child_request_id] = s; 
    } 
    return parent_request_id; 
    } 

    /* 
    * sets up mutli queries to only run callback when all complete 
    * the requestobject is key=>query assoc to which results are assign the same key 
    * when all results complete the callback is run giving the request_id in the normal way 
    * to return the multi result object 
    */ 
    Ajax_m.prototype.multiRequest = function (requestobject, callback) { 
    var parent_request_id = this.request({ajaxRequestSubType: "multirequest_parent", request_total: count(requestobject), request_returned: 0, id_list: [], request: {}, data: {}, callback: callback}); 
    for (var r in requestobject) { 
     /*var child_request = { 
     request: requestobject[r], 
     ajaxRequestSubType: "multirequest_child", 

     }*/ 
     var child_request = requestobject[r]; 
     child_request.multirequest_parent = parent_request_id; 
     child_request.flag_multiRequestChild = true; 
     var child_request_id = this.request(child_request); 
     this.server_data[parent_request_id].id_list[child_request_id] = r; 
    } 
    return parent_request_id; 
    } 

    /* 
    * sets up facility for javascript to download data locally 
    * there is no callback facility required as this is a one-way request 
    * with a url returned pointing to the resultant file, this is ultimately sent as a new 
    * window request to the file which will be handled on the native machine settings 
    * 
    * for integrity and security the server sets a unique filename ending 
    * 
    * First a meta query is sent to process what action to take - eg inform that data is emailed when ready if a length query 
    * This is then fed back to the user as to what is happening before the actual query can begin. 
    * @param type determines what download process should be used 
    * @param dataArgs determines how the data is retrieived 
    */ 
    Ajax_m.prototype.requestDownload = function (fileprefix, type, downloadData) { 
    view.dialogOpen({ 
     title: "Download", 
     dialogbody: "preparing download . . .", 
     closeButton: false//change to false after test 
    }); 
    this.request({ajaxRequestType: "requestDownload", fileprefix: fileprefix, ajaxRequestSubType: type, downloadData: downloadData}); 
    //this.server_data[downloadid].callbacktype = action; 
    } 

    /* 
    * opens url to processed data downloadRequest in a new window/tab 
    */ 
    Ajax_m.prototype.downloadrun = function (reqobj) { 
//getRequestResult 
    var meta = this.getRequestResult(reqobj.request_id); 
    switch (reqobj.ajaxRequestSubType) { 
     case "jscsv": 
     view.dialogOpen({ 
      title: "Download", 
      dialogbody: "Your file download has finished processing.<br />Please ensure you have popups enabled for this site to be able to access the file.", 
      closeOK: true 
     }); 
     window.open(meta.downloadurl, "download"); 
     break; 
     case "dbcsv": 
     view.dialogOpen({ 
      title: "Download", 
      dialogbody: meta.msg, 
      closeOK: true 
     }); 
     this.request({ajaxRequestSubType: "downloadrun", filename: reqobj.filename, type: reqobj.type, downloadsource: reqobj.downloadsource}, ''); 
     break; 
    } 
    } 

    /* 
    * kills data (returning requested will be ignored) 
    */ 
    Ajax_m.prototype.reset = function() { 
    for (var s in this.server_data) { 
     if (this.server_data[s].ajax) { 
     this.server_data[s].ajax.abort(); 
     } 
    } 
    this.server_data = new Array(); 
    this.request_index = 0; 
    } 

    /* 
    * relates misc data to query eg 
    */ 
    Ajax_m.prototype.setMisc = function (request_id, miscobject) { 
    this.server_data[request_id].misc = miscobject; 
    } 

    /* 
    * gets misc data to query eg 
    */ 
    Ajax_m.prototype.getMisc = function (request_id) { 
    return this.server_data[request_id].misc; 
    } 

    /* 
    * get orig query sent 
    */ 
    Ajax_m.prototype.setAjaxRequestType = function (type) { 
    this.reqType = type; 
    } 

    /* 
    * get orig query sent 
    */ 
    Ajax_m.prototype.setDataType = function (type) { 
    this.dataType = type; 
    } 

    /* 
    * get orig query sent 
    */ 
    Ajax_m.prototype.getRequest = function (request_id) { 
    return this.server_data[request_id].request; 
    } 

    /* 
    * return result data for given request id 
    */ 
    Ajax_m.prototype.getRequestResult = function (id) { 
    var data;//leave as undefined so code fails in the client 
    if (this.server_data[id]) { 
     data = this.server_data[id].data; 
    } 
    return data; 
    //return data; 
    } 

    /* 
    * return result data for given request id indexed by a field name 
    * if its not unique there will be data loss and a 'distinct' set will be returned 
    */ 
    Ajax_m.prototype.getRequestResultByCol = function (id, colname) { 
    var reqdata = this.getRequestResult(id); 
    var data = {}; 
    for (var r in reqdata) { 
     data.r[colname] = data.r; 
     delete data.r[colname][colname]; 
    } 
    return data; 
    //return data; 
    } 

    /** 
    * return a single value for given request id, if request id did actual generate 
    * multiple values then only the first is returned 
    * if this was a multirequest, the named key of the multi request is required 
    */ 
    Ajax_m.prototype.getRequestValue = function (id, multi_id) { 
    var retval; 
    if (!this.server_data[id].ismultiparent) { 
     retval = this.server_data[id].data[0]; 
    } else { 
     retval = this.server_data[id].data[multi_id][0]; 
    } 
    if (retval == undefined) { 
     retval = null; 
    } 
    return retval; 
    } 



    /* 
    * removes a query and data from memory 
    */ 
    Ajax_m.prototype.deleteRequest = function (request_id) { 
    delete this.server_data[request_id]; 
    } 


    Ajax_m.prototype.error = function (serverData, st, ert) { 
//all errors should have been handled, but just in case 
    var errorReport = "error"; 
    errorReport += st; 
    alert("error"); 
    } 

    /********************************************************************************************************** 
    INTENDED AS PRIVATE FUNCTIONS 
    **********************************************************************************************************/ 

    /* 
    * sets result data for this instance for given query id - eliminates the need for eval unknown ajax data 
    */ 
    Ajax_m.prototype.setRequestResult = function (request_id, data) { 
    this.server_data[request_id].data = data; 
    } 

    /* 
    * compiles the data from the multi query parts into the array entry referenced by the query_index returned 
    * from client code calling the multiquery function. This also allows the required callback with a reference id to this data 
    */ 
    Ajax_m.prototype.multiRequestFinish = function (multirequestid) { 
    var requestobj = this.server_data[multirequestid]; 
    var multidata = {}; 
    var compactdata; 
    for (var i in requestobj.id_list) { 
     requestobj.data[requestobj.id_list[i]] = this.getRequestResult(i); 
     this.deleteRequest(i); 
    } 
    eval(requestobj.callback + "(" + multirequestid + ")"); 
    } 

    /* 
    * finalises multisubmit and runs callback 
    */ 
    Ajax_m.prototype.multiSubmitFinish = function (multirequestid) { 
    var requestobj = this.server_data[multirequestid]; 
    var multidata = {}; 
    var compactdata; 
    for (var i in requestobj.id_list) { 
//requestobj.data[requestobj.id_list[i]] = this.getRequestResult(i); 
     this.deleteRequest(i); 
    } 
    eval(requestobj.callback + "(" + multirequestid + ")"); 
    } 

}