ブラりザデヌタベヌスのロヌカルストレヌゞを䜿甚しおJavascriptで「マむンドマップ」を䜜成する



これは、メモリカヌド゚ディタの小さな教育的な䟋です 。 非垞に詳现なコメントず簡単なコヌドのため、それを理解するこずは問題になりたせん。 この蚘事は、Javascriptを知っお孊ぶ人を察象ずしおいたす。



ブラりザデヌタベヌスを䜿甚するメモリカヌド゚ディタを䜜成する機胜に぀いお説明したす。 さらに、LocalStorageではなく、5メガバむトを超えるこずはできたせん。 特定のブラりザで利甚可胜なものに応じおIndexedDBたたはwebSQLを䜿甚するため、デヌタ量は100〜200メガバむトを超えるこずがありたす。



゜ヌスはGithubで公開されおいたす。



520行のコヌドに察応したすが、マップでは、ノヌドを䞀緒にドラッグしたり、削陀したり、名前を倉曎したり、新しいノヌドを䜜成したりできたす。 たた、コンテキストメニュヌから120個のアむコンのいずれかを割り圓おるこずもできたす。



ミニマリズムの秘密は、 戊闘でテストされたプラグむンを䜿甚するこずです

  1. Ydn.db-最適なメ゜ッドず単䞀のAPIを自動的に遞択しお、ブラりザヌデヌタベヌスに情報を保存する
  2. jQueryコンテキストメニュヌ-Javascriptを䜿甚しお動的に入力できるコンテキストメニュヌ
  3. jsPlumb -HTML芁玠間に線を描画するための拡匵機胜
  4. jQuery UI-ドラッグアンドドロップ-アむテム間でアむテムをドラッグアンドドロップする




PSたた、「シングルトン」の䜜成方法、jQueryず組み蟌みの$ .Deferredオブゞェクト、 LiveReloadプラグむンを䜿甚した非同期プログラミングを容易にする方法を孊習したす。





急いでいる人のためのコメント付きプログラムコヌド


倚くはこれ以䞊読むこずはできたせんが、単にコヌドに慣れるだけです。

非垞に詳现なコメント付きのメむンJavaScriptコヌド
var API_4_MINDMAP = function(){ //singleton -      if ( (typeof arguments.callee.instance=='undefined') ) { //     arguments.callee.instance = new function() { var this_api = this; //  ,     var my_all_data = {}; //    var my_all_data_template = { //  ,     "n1":{ id:1, parent_id:0, title:" <br> <br>"+ "  <br> .<br>Javascript" }, "n2":{ id:2, parent_id:1, title:"", icon:"icon-gift" }, "n3":{ id:3, parent_id:2, title:"   ", icon:"icon-flow-line" }, "n5":{ id:5, parent_id:3, title:"  jsPlumb", icon: "icon-link" }, "n4":{ id:4, parent_id:3, title:"  -  SVG" }, "n7":{ id:7, parent_id:6, title:"  jQuery ContextMenu", icon: "icon-link" }, "n8":{ id:8, parent_id:1, title:" ", icon: "icon-lamp" }, "n9":{ id:9, parent_id:8, title:"Javascript + jQuery — 520 " }, "n10":{ id:10, parent_id:2, title:"   ", icon: "icon-floppy-1" }, "n11":{ id:11, parent_id:17, title:"IndexedDB" }, "n12":{ id:12, parent_id:17, title:"webSQL" }, "n13":{ id:13, parent_id:17, title:"LocalStorage" }, "n14":{ id:14, parent_id:10, title:"  Ydn.db", icon: "icon-link" }, "n15":{ id:15, parent_id:10, title:"   " }, "n16":{ id:16, parent_id:2, title:"   Javascript", icon: "icon-cd" }, "n17":{ id:17, parent_id:10, title:"" }, "n18":{ id:18, parent_id:6, title:"  " }, "n20":{ id:20, parent_id:8, title:"CSS — 220 " }, "n19":{ id:19, parent_id:8, title:"HTML — 50 " }, "n22":{ id:22, parent_id:16, title:"    " }, "n23":{ id:23, parent_id:16, title:"   " }, "n24":{ id:24, parent_id:2, title:"  ", icon: "icon-emo-wink" }, "n6":{ id:6, parent_id:2, title:" ", icon: "icon-list" }, "n25":{ id:25, parent_id:24, title:"   Fontello", icon: "icon-link" }, "n27":{ id:27, parent_id:2, title:"Drag&Drop jQuery UI", icon: "icon-link" }, "n26":{ id:26, parent_id:24, title:"    " } }; this.jsSaveAllToDB = function() { //      $.each(my_all_data, function(i, el){ db.put("mindmap_db", el ).done(function(){ }); }); } this.jsLoadAllFromDB = function() { //          var d=new $.Deferred(); //    my_all_data = {}; //  db.values("mindmap_db",null,99999999).done(function(records) { if(records.length && false) { $.each(records, function(i, el){ my_all_data["n"+el.id] = {}; my_all_data["n"+el.id] = el; }); } else { //   ,          my_all_data = my_all_data_template; this_api.jsSaveAllToDB(); } d.resolve(); // ,     done }); return d.promise(); //,    ,    } this.jsFind = function(id, changes) { //   id     //    ,  n     id var answer = my_all_data["n"+id]; if(!answer) return false; //     if(changes) { //   ,     $.each(changes, function(name_field, new_field_value){ answer[name_field] = new_field_value; }); db.put("mindmap_db", answer ).done(function(){ //      console.info("     "); //    }); } return answer; } this.jsFindByParent = function(parent_id) { //    parent_id var answer = []; $.each(my_all_data, function(i,el){ //      = parent_id if((el.parent_id == parent_id) && (!el.del)) answer.push(el); }); return answer; } this.jsAddNew = function(parent_id, title) { //    parent_id var max_id = 0; $.each(my_all_data, function(i,el){ //  id if(el.id>max_id) max_id = el.id; }); var new_id = (parseInt(max_id)+1); //  id my_all_data["n"+new_id] = {}; //   my_all_data["n"+new_id] = {id:new_id, parent_id: parent_id, title: title}; //  return new_id; } //   ,     this.jsRecursiveByParent = function(id, recursive_array) { if(!recursive_array) recursive_array = []; var answer = this_api.jsFindByParent(id); $.each(answer,function(i,el) { //      ,    recursive_array.push(el); recursive_array = this_api.jsRecursiveByParent(el.id, recursive_array); }); return recursive_array; } this.jsDeleteById = function(id) { //       if(confirm("  №"+id+"   ?")) { var childs = this_api.jsRecursiveByParent(id); $.each(childs, function(i, el){ api4mindmap.jsFind(el.id, {del:1}); //"" -       }); if(id!=1) api4mindmap.jsFind(id, {del:1}); // ,    №1 } } this.jsRenderAllMap = function(focus_id) { //      if(!focus_id) focus_id = 1; var html = "<ul myid='"+focus_id+"'>"; html = this_api.jsRenderOneParent(focus_id, html); //  html += "</ul>"; $("#mindmap").html(html); jsMakeDroppable(); //    } this.jsRenderOneParent = function(parent_id, html) { //     html += "<li id='node_"+parent_id+"' myid='"+parent_id+"'>"; html += "<div class='big_n_title'>"; html += this_api.jsRenderOneElement(parent_id); //   html += "</div>"; var childs = this_api.jsFindByParent(parent_id); //   if(childs.length) { html += "<ul class='childs' myid='"+parent_id+"'>"; } $.each(childs, function(i,el){ html = this_api.jsRenderOneParent(el.id,html); //   ,    }); if(childs.length) { html += "</ul>"; } html += "</li>"; return html; } this.jsRenderOneElement = function(id) { //   var element = this_api.jsFind(id); //  var childs_count = this_api.jsFindByParent(id).length; //-    var icon_type = ''; if(element.icon) icon_type = element.icon; //  ,   if(childs_count>0) { //   var collapser_html = "<div class='collapse'></div>"; //   ,   var icon = "<div class='type_icon'><i class='icon-folder-1 folder'><div class='count'>"+ childs_count+"</div></i><i class='"+icon_type+"'></i>"+"</div>"; } else { var collapser_html = ""; var icon = "<div class='type_icon'><i class='"+icon_type+"'></i></div>"; } var answer = icon+"<div class='n_title' contenteditable='true'>"+element.title+ "</div><div class='contextmenu'></div>"+collapser_html; return answer; } this.jsDrawMindmap = function(focus_id) { //     var line_cache = []; $("#mindmap ul:visible").each(function(){ //   ul var ul_id = $(this).attr("myid"); var childs = this_api.jsFindByParent(ul_id); $.each(childs, function(i,el){ // ,      var target = el.id; if(!$("li[myid='"+target+"']"+" .big_n_title:first").hasClass("_jsPlumb_endpoint_anchor_")) { var parent_id = el.parent_id; line_cache.push( {source: parent_id, target: target} ); } }); }); if(line_cache.length) { //   ,     if(!myjsPlumb.isSuspendDrawing()) { myjsPlumb.setSuspendDrawing(true, true); console.info("set_suspend"); } } $.each(line_cache, function(i, el){ if(el.source == 1) { //        anchor1 = [ 1, 0.5, 1, 0, -1, -1 ]; } else { anchor1 = [ 1, 1, 1, 0, -1, -1 ]; //    } //   : var p1 = myjsPlumb.addEndpoint("node_"+el.source+" .big_n_title:first", { anchor: anchor1 }); //   : var p2 = myjsPlumb.addEndpoint("node_"+el.target+" .big_n_title:first", { anchor: [ 0, 1, -1, 0, 1, -1 ]}); //   : var count = this_api.jsFindByParent(el.source).length; if(count>10) { //  ,     var LineType = "Straight"; } else { var LineType = "Bezier"; //   } //  ,    myjsPlumb.connect({source: p1, target: p2, scope:"someScope", deleteEndpointsOnDetach:true, connector:[ LineType, { curviness: 30, cornerRadius: 20 } ]}); }); } //jsDrawMindmap this.jsRefreshMindmap = function() { //         myjsPlumb.reset(); //   var save_scroll_top = $("#mindmap").scrollTop(); //  ,   var save_scroll_left = $("#mindmap").scrollLeft();//     var hidden_elements = []; //    $(".hide").each(function(){ hidden_elements.push($(this).attr("myid")); }); api4mindmap.jsRenderAllMap(1); //    $.each(hidden_elements, function(i, el){ // ,    . $("#node_"+el).addClass("hide"); }); api4mindmap.jsDrawMindmap(1); // ,      onResize(); //    $("#mindmap").scrollTop(save_scroll_top); //  ,   $("#mindmap").scrollLeft(save_scroll_left);//     } this.jsRegAllKeys = function() { //    $("#mindmap").on("keydown", ".n_title", function(e){ //  Enter if(e.keyCode==13) { e.preventDefault(); $(this).blur(); // ,      } }); $("#mindmap").on("keyup", ".n_title", function(e){ e.preventDefault(); if(e.keyCode==13) $(this).blur(); onResize(); // ,   ,  ,  }); $("#mindmap").on("blur", ".n_title", function(){ //  ,   var n_title_text = $(this).html(); var id = $(this).parents("li:first").attr("myid"); if(n_title_text.length==0) n_title_text = " "; //  ,   . $(this).html( strip_tags(n_title_text) ); //     this_api.jsFind(id, {title:n_title_text}); //        onResize(); //  }); $("#mindmap").on("click", ".n_title", function(){ //   ,  $(this).focus(); }); $("#mindmap").on("focus", ".n_title", function(){ // ,    var ntitle = $(this); setTimeout(function(){ if(ntitle.is(":focus")) document.execCommand('selectAll',false,null); },3); //        Firefox }); $("#mindmap").on("click", ".collapse", function(){ //     $(this).parents("li:first").toggleClass("hide"); //  api4mindmap.jsDrawMindmap(1); // ,   onResize(); return false; }); var font_size = 14; //   $("#zoom_in").on("click", function(){ //   font_size += 1; $("#mindmap").css("font-size", font_size+"px"); onResize(); return false; }); $("#zoom_out").on("click", function(){ //   font_size -= 1; $("#mindmap").css("font-size", font_size+"px"); onResize(); return false; }); $("#collapse_all").on("click", function(){ // "  " $("#node_1 ul li").addClass("hide"); onResize(); return false; }); $("#expand_all").on("click", function(){ // "  " $("#node_1 ul li").removeClass("hide"); onResize(); return false; }); } //jsRegAllKeys } } return arguments.callee.instance; //   } function onResize() { myjsPlumb.setSuspendDrawing(false, true); //   } function jsGetIcons(n) { //    var icons = {}; icons[0] = ["progress-0","progress-1","progress-2","progress-3","dot","dot-2","dot-3","star-empty","star","record"]; icons[1] = ["check","heart-empty","heart","bookmark-empty","bookmark","ok-2","help","wallet","mail-2","cloud"]; icons[2] = ["tree","chat-2","article-alt","volume","flash","aperture-alt","layers","steering-wheel","skiing","flight"]; icons[3] = ["lock-open","lock","umbrella","camera","book-open","clock-1","plus","minus","trash","music"]; icons[4] = ["calculator","address","pin","vcard","basket-1","swimming","youtube","leaf","mic","target"]; icons[5] = ["monitor","phone","download","bell","at","pause","play","stop-1","flag","key"]; icons[6] = ["users-1","eye","inbox","brush","moon","college","fast-food","coffee","top-list","bag"]; icons[7] = ["chart-area","info","home-1","hourglass","attention","scissors","tint","guidedog","archive","flow-line"]; icons[8] = ["emo-grin","emo-happy","emo-wink","emo-sunglasses","emo-thumbsup","emo-sleep","emo-unhappy","emo-devil","emo-surprised","emo-tongue"]; icons[9] = ["plus","minus","keyboard","fast-fw","to-end","to-start","cancel-circle","check","flash","feather"]; icons[10] = ["plus-circle","pencil-alt","target-1","chart-pie","adjust","user-add","volume","install","flow-cascade","sitemap"]; icons[11] = ["minus-circle","clock-1","light-down","light-up","lamp","upload","picture-2","dollar","gift","link-1"]; answer = {}; $.each(icons, function(j, icon_group){ sub_icons = {}; $.each(icons[j], function(i, icon){ sub_icons["icon-"+icon] = {}; sub_icons["icon-"+icon] = {name:icon, icon: "icon-"+icon}; }); answer["icon-group"+icon_group] = {}; answer["icon-group"+icon_group] = {name:" №"+(parseInt(j)+1), icon: "icon-"+icons[j][0], items: sub_icons}; }); return answer; //     } function jsMakeDroppable() { //    $(".n_title").not("ui-draggable").draggable({ zIndex: 999, delay:50, revert: false, // will cause the event to go back to its helper:"clone", appendTo: "body", refreshPositions:true }); $( ".n_title" ).not("ui-droppable").droppable({ accept: ".n_title", activeClass: "ui-can-recieve", tolerance: "pointer", hoverClass: "ui-can-hover", over: function (event, ui) { //$(this).click(); }, drop: function( event, ui ) { //console.info("drop-all",usedOverlays,ui,ui.draggable[0] ); var my_draggable = $(ui.draggable[0]); var my_droppable = $(event.target); my_draggable_id = my_draggable.parents("li:first").attr("myid"); my_droppable_id = my_droppable.parents("li:first").attr("myid"); if( jsCanDrop(my_draggable_id, my_droppable_id) ) { //,    api4mindmap.jsFind(my_draggable_id, {parent_id:my_droppable_id}); api4mindmap.jsRefreshMindmap(); $(".ui-draggable-dragging").remove(); //  ,   } else { alert("      "); } } }); } function jsCanDrop(draggable_id, droppable_id) { // ,        var can_drop = true; var all_childs = api4mindmap.jsRecursiveByParent(my_draggable_id); $.each(all_childs, function(i,el){ console.info(el.id, droppable_id); if(el.id == droppable_id) can_drop = false; }); if(draggable_id == droppable_id) var can_drop = false; return can_drop; } //      function strip_tags( str ){ if(!str) return ""; answer = str.replace(/<\/?[^>]+>/gi, ''); answer = answer.replace(/\n/gi, ''); return answer; } var myjsPlumb; //    ///////////////////////   html //////////////////////// function jsDoFirst() { api4mindmap = new API_4_MINDMAP(); //  api  "" jsPlumb.Defaults.Container = $("#mindmap"); // ""  myjsPlumb = jsPlumb.getInstance({ DragOptions: { cursor: 'pointer', zIndex: 2000 }, PaintStyle:{ lineWidth:1, strokeStyle:"#888" }, Connector:[ "Bezier", { curviness: 30 } ], Endpoint:[ "Blank", { radius:5 } ], EndpointStyle : { fillStyle: "#567567" }, Anchors : [[ 1, 1, 1, 0, -1, -1 ],[ 0, 1, -1, 0, 1, -1 ]] }); var icons_html = jsGetIcons(0); //         $.contextMenu({ //          .contextmenu selector: '.contextmenu', trigger: 'left', callback: function(key, options) { var id = $(this).parents("li:first").attr("myid"); if( /icon-/ig.test(key) ) { //  api4mindmap.jsFind(id, {icon:key}); api4mindmap.jsRefreshMindmap(); } else if(key == "delete") { //    api4mindmap.jsDeleteById(id); api4mindmap.jsRefreshMindmap(id); } else if(key == "add_down") { //  var parent_id = api4mindmap.jsFind(id).parent_id; var new_id = api4mindmap.jsAddNew(parent_id, " "); api4mindmap.jsRefreshMindmap(); $("#node_"+new_id+" .n_title").focus(); } else if(key == "add_right") { //  var new_id = api4mindmap.jsAddNew(id, " "); $(this).parents("li").removeClass("hide"); api4mindmap.jsRefreshMindmap(); $("#node_"+new_id+" .n_title").focus(); } }, delay:0, items: { "add_down": {"name":" ", "icon": "icon-down-1"}, "add_right": {"name":" ", "icon": "icon-right-1"}, "sep1": "--------", "delete": {"name":"", "icon": "icon-trash"}, "context_make_did1011": {"name": "", "icon": "icon-emo-wink", "items": icons_html //     } } }); //    var mindmap_store_schema = { //   name: "mindmap_db", //  keyPath: 'id', //       , autoIncrement: false }; var schema = { //   stores: [mindmap_store_schema] }; if( navigator.userAgent.toLowerCase().indexOf("android") !=-1 ) { var options = {mechanisms: ['websql', 'indexeddb']}; // websql   } else { var options = {}; // indexeddb    ),      } db = new ydn.db.Storage('_all_mindmap', schema, options); //    api4mindmap.jsLoadAllFromDB().done(function(){ //        api4mindmap.jsRegAllKeys(); //  api4mindmap.jsRenderAllMap(1); //    №1 api4mindmap.jsDrawMindmap(1); // ,      onResize(); //  }); //       }
      
      









プログラミング時に䜿甚するツヌル


今のずころ、コヌドの研究を延期したす。 最初に、䜿甚するツヌルに぀いお簡単に説明したす。 倚くの新参者はそれらに぀いお知らず、これに時間を倱いたす。



私はCodaで、時にはSublime Textでプログラムしおいたす。 Codaはより銎染みがありたすが、コヌドを色付けするこずで少し遅くなりMac専甚、Sublime Textは非垞に高速で、どのプラットフォヌムでも動䜜したすが、たず、ただ慣れおいたせん。次に、サヌバヌ䞊のCodaに盎接アクセスするのが奜きです。耇数のファむルをすばやく修正したす。 そしお、私は端末を䜿甚しおCoda経由でDebianず通信したす。



私にずっお䜜業速床の真の突砎口は、 GITの発芋でした。 これはバヌゞョン管理システムです。 公匏のGitHubプログラムで䜿甚しおいたす 。





Githubをコヌドのクラりドストレヌゞずしお䜿甚し、それを䜿甚しおリリヌスを公開したす。 サむトのバヌゞョンを「リリヌス」するには、次のようにしたす。

  1. ロヌカルマシンでサむトの動䜜を確認し、「コミット」を実行したす。 倉曎を確認したす䞊の図の[コミット]ボタンを参照
  2. ボタンを1぀抌すだけでサヌバヌに「プッシュ」が倉曎されたす䞋郚の同じりィンドりに[同期]ボタンがありたす
  3. 私はドむツのサヌバヌの SSH経由でタヌミナルに行き、コマンドを実行したす

    git pull https// myuser_namemysslpassword@github.com/Imater/tree.git master
  4. すべおのJSおよびCSSファむルを圧瞮し、それらからコメントをスロヌし、それらを1぀のjsファむルず1぀のcssファむルに圧瞮するスクリプトを実行したす。 HTMLペヌゞに挿入するファむルが少ないほど、サむトの読み蟌みが速くなりたす




コヌドを操䜜しおいる間、私は垞にChromeずそのコン゜ヌルを開いおいたす。 コン゜ヌルでは、䜜成された関数を詊しお、デヌタを操䜜し、組み蟌みデバッガヌを䜿甚しおコヌドをデバッグできたす。





コン゜ヌルず開発者ツヌルの䜿甚方法を孊び、倚くの時間を節玄しおください。



次に、F5キヌのペむントに぀いお説明したすMacOSの堎合-cmd + r。 最近発芋されたLiveReload 。 WinずMacの䞡方のバヌゞョンがありたす。



プログラムをむンストヌルしおから、プラグむンをChromeたたは別のブラりザヌの䞋に眮くか、メむンHTMLファむルのbodyタグの盎埌にコヌドを貌り付けたす。

 <script>document.write('<script src=\"http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1\"></' + 'script>')</script>
      
      







そしおその埌、あなたは倚くの喜びを埗たす。 シナリオは次のずおりです。プログラムするWebサむトを開き、CSSたたはJavascriptでコヌドを蚘述するか、「livereload」が監芖するフォルダヌ内の画像を眮き換えたす。保存するずすぐにサむトが曎新されたす。 CSSを眮き換えるず、ペヌゞをリロヌドせずに倉曎が即座に適甚されたす。



最埌に、ツヌルの説明では、ボリュヌムの最倧70を節玄し、サむトの読み蟌みを高速化するPNGむメヌゞレデュヌサヌをお勧めしたす。



メモリカヌドを䜜成するためのプログラムコヌドの説明


すべおのコヌドはGithubに投皿されおいたす。 ダりンロヌドしお、任意のフォルダヌに展開できたす。 必芁なものはすでにリポゞトリにありたす。 フォルダヌ内のすべおのプラグむン。 コヌド内のコメントは非垞に詳现です。



基本から始めたしょう。 私はすべおの倚くの機胜をシングルトンでラップするのが倧奜きです。 私は次のようにしたす

 var API_4_MINDMAP = function(){ //singleton -      if ( (typeof arguments.callee.instance=='undefined') ) { //     arguments.callee.instance = new function() { var my_all_data = {}; var this_api = this; //  ,      this.jsAlert = function( name ) { if( prompt("Hello "+name+", are you ok?") ) { var is_ok = true; } else { var is_ok = false; } my_all_data[name] = {}; my_all_data[name] = {name: name, hi_is_ok: is_ok}; return my_all_data; } } return arguments.callee.instance; //   } api4mindmap = new API_4_MINDMAP(); //  api  "" console.info( api4mindmap.jsAlert("Habrahabr") );
      
      





このアプロヌチの利点は、そのような「シングルトン」内に倧量のデヌタを保存でき、ナヌザヌやプラグむンがデヌタを倉曎するこずを恐れないこずです。 関数ず倉数を分離したす。 そしお、緎習から、コン゜ヌルに「api4mindmap.js ...」ず入力しお、䜜成したすべおの関数のポップアップリストを埅ちたす。 速くお䟿利。



か぀お、䞊蚘の䟋では、my_all_data配列のデヌタが関数呌び出し間で保存されるこずが発芋されたした。



次に、䜿甚するプラグむンに぀いお説明したす。



Ydn.db-ブラりザヌデヌタベヌス




これは、単䞀のAPIを䜿甚しおロヌカルブラりザヌデヌタベヌスのデヌタを保存および読み取るこずができるjQueryプラグむンです。 モバむルを含むあらゆるプラットフォヌムで動䜜したす。 Phonegapでも。



ほずんどの機胜は䜿甚したせんが、䞻に次の堎合に䜿甚したす。

  this.jsLoadAllFromDB = function() { //          var d=new $.Deferred(); //    my_all_data = {}; //  db.values("mindmap_db",null,99999999).done(function(records) { if(records.length) { $.each(records, function(i, el){ my_all_data["n"+el.id] = {}; my_all_data["n"+el.id] = el; }); } else { //   ,          my_all_data = my_all_data_template; this_api.jsSaveAllToDB(); } d.resolve(); // ,     done }); return d.promise(); //,    ,    } this.jsFind = function(id, changes) { //   id     //    ,  n     id var answer = my_all_data["n"+id]; if(!answer) return false; //     if(changes) { //   ,     $.each(changes, function(name_field, new_field_value){ answer[name_field] = new_field_value; }); db.put("mindmap_db", answer ).done(function(){ //      console.info("     "); //    }); } return answer; }
      
      





これは、メモリカヌド゚ディタのコヌドの䟋です。 非垞に簡単なコマンドがありたすdb.values "mindmap_db"、null、99999999-IndexedDbテヌブルChromeの堎合からすべおの芁玠を読み取り、しばらくしおから.doneパラメヌタヌにある関数に戻りたす。 したがっお、デヌタベヌスからアむテムを読み取るこずができたす。 次のコマンドを䜿甚しお1぀の芁玠を読み取るこずができたすdb.get "mindmap_db"、5-これは、id = 5の芁玠を考慮する方法です。



デヌタベヌスに曞き蟌むには、コマンドdb.put "mindmap_db"、answerを䜿甚したす。 このコマンドは非同期であり、ブラりザヌは実行を埅機しないため、䜜業の速床が䜎䞋するこずはありたせん。 そのため、このプログラムはChromeでより高速に実行されたす。



非同期コマンドを䜿甚するには、jQueryに組み蟌たれた$ .Deferredオブゞェクトを䜿甚したす。 䞊蚘の䟋を瀺したす。 次のコマンドを䜿甚しお、すぐに結果を返すこずを関数の最埌で単に玄束したす。return d.promisex; そしお、関数のすべおが完了したら、たずえばデヌタがサヌバヌに送信されたら、d.resolve200を実行したす。 次に、.done関数が実行され、パラメヌタヌxが枡されたす。



これは、盞互に関数を蚘述できないようにするため、非垞に䟿利です。 たた、$ whenのチヌムを勉匷するこずをお勧めしたす。 同時に起動する倚くの非同期関数があり、すべおの非同期関数が完了した盎埌に䜕かを実行したい堎合に䜿甚したす。 以䞋に䟋を瀺したす。

 function jsDo() { var dfdArray = []; for(var i=0; i<1000; i++) { dfdArray.push( jsAsync() ); } $.when.apply(null, dfdArray).then( function(){ alert("  ") } ); } function jsAcync() { var d = new $.Deferred(); setTimeout(function(){ d.resolve(); }, Math.random()*5000 ); return d.promise(); }
      
      





実際、ここではすべおの「玄束」が配列に入力され、$ .whenコマンドに枡されたす。このコマンドは、最埌の玄束が満たされた瞬間に「.done」機胜を実行したす。



Ydn.dbを䜿甚するず、ブラりザでのストレヌゞの方法を考慮するこずなくデヌタを操䜜できたす。これは、その倚様性を1぀のAPIにラップしおいるためです。 特に、むンデックスの操䜜、遞択、フィルタの適甚、テヌブルの合蚈の蚈算などを行うこずができたす。 しかし、この䟋では、デヌタの保存ず読み取りにのみ䜿甚し、むンデックスmyロヌルはmy_all_data配列によっお再生されたす。これは非垞に高速です。 同時に、api4mindmap.jsFindid、{title "new_title"}関数がこの配列をすぐに曎新し、デヌタを非同期でデヌタベヌスに送信するこずにより、デヌタの安党性が確保されたす。 ただし、それにもかかわらず、メモリカヌド内のノヌドのタむトルを倉曎し、ブラりザをすぐに曎新するず、すべおのデヌタが保存されたす。 ブラりザヌのデヌタベヌスは高速で信頌性が高く、100メガバむトを超える情報を保存できたす。



Ydn.dbを調べた埌、玄5メガバむトのLocalStorageの制限を忘れるこずができたす。 ナヌザヌが5メガバむトごずにデヌタを保存する蚱可を求めるのは、Chromeが芁求しないだけです。



このプラグむンは、AndroidおよびiOSでうたく機胜したす。 ただし、゚ラヌを回避するために、AndroidでIndexedDBの遞択をオフにする必芁がある堎合があるこずに泚意しおください。 泚目すべきは、Internet Explorerの最新バヌゞョンはIndexedDBを䜿甚しおいるため、非同期のためにそのようなアプリケヌションの䜜業が高速化されるこずです。 䞀床に1000個の芁玠を保存するず、それらは䞊行しお実行されたすが、速床は異なりたす。これは、順次蚘録よりも高速です。



jsPlumb-任意のブラりザヌでSVGラむンを描画する




Canvasを䜿甚しお、htmlペヌゞのさたざたな芁玠間に線を描画できたすが、倚くの欠点がありたす。 たずえば、4000 x 4000 pxなど、かなりのサむズのCanvasを䜜成する必芁がありたすが、これは䞍安定なブラりザヌ操䜜に぀ながりたす。 ラむンはラスタヌになり、最新のRetinaスクリヌンでは、ベクタヌラむンよりも芋た目が悪くなりたす。 そしお最悪なのは、メモリヌカヌドに文字を入力するたびに、これらの1600䞇ピクセルすべおが再描画を必芁ずするこずです。



jsPlumbは、SVGに各線を描画しお適切な堎所に配眮し、絶察CSSプロパティず蚈算された座暙を配眮したす。 1぀のコマンドですべおの行を即座に再描画するこずができたす。 実際、開始点ず終了点を䞀床指定するだけで、それらを線で぀なぐだけでプラグむンを忘れるこずができたす。 ほが3チヌムで、回線の凊理方法を知っおいたす。



サむトには各芁玠をマりスで移動できる䟋がありたすが、行は芁玠の埌に速床を萜ずさずに移動したす。





階局構造、単玔なグラフ、トレヌニング説明しおいる芁玠に矢印の付いた線で衚瀺、䌁業の組織構造、図など、描画に䟿利です。 iOSおよびAndroidを含むほがすべおのブラりザヌで動䜜したす。



jQueryコンテキストメニュヌ -コンテキストメニュヌ


私が芋たすべおのメニュヌプラグむンは、独自のhtml階局を䜜成するために䜿甚したす。 たた、このプラグむンでは、オブゞェクトの配列を䜿甚しお、シンプルでほがJSON圢匏の構造を䜜成できたす。





次のコヌドを䜿甚しお、メニュヌで䞀連のコマンドを指定できたす。

  $.contextMenu({ //     .contextmenu selector: '.contextmenu', trigger: 'left', callback: function(key, options) { var id = $(this).parents("li:first").attr("myid"); if( /icon-/ig.test(key) ) { //  api4mindmap.jsFind(id, {icon:key}); api4mindmap.jsRefreshMindmap(); } else if(key == "delete") { //    api4mindmap.jsDeleteById(id); api4mindmap.jsRefreshMindmap(id); } else if(key == "add_down") { //  var parent_id = api4mindmap.jsFind(id).parent_id; var new_id = api4mindmap.jsAddNew(parent_id, " "); api4mindmap.jsRefreshMindmap(); $("#node_"+new_id+" .n_title").focus(); } else if(key == "add_right") { //  var new_id = api4mindmap.jsAddNew(id, " "); $(this).parents("li").removeClass("hide"); api4mindmap.jsRefreshMindmap(); $("#node_"+new_id+" .n_title").focus(); } }, delay:0, items: { "add_down": {"name":" ", "icon": "icon-down-1"}, "add_right": {"name":" ", "icon": "icon-right-1"}, "sep1": "--------", "delete": {"name":"", "icon": "icon-trash"}, "context_make_did1011": {"name": "", "icon": "icon-emo-wink", "items": icons_html //     } } });
      
      







アむテムのアむテムに泚意しおください、すべおが非垞に明確で矎しいです。 さらに、コヌルバック関数にコンテキストメニュヌによっお呌び出されるすべおの関数を䞀緒に栌玍するず、混乱が少なくなりたす。



私がしなければならなかった唯䞀のこずは、ラスタヌアむコンではなくFontelloフォントのアむコンを描画しないようにプラグむンスクリプトを埮調敎するこずでした。



このコンテキストメニュヌの䞻な利点は、キヌを制埡しお項目を遞択したり、ホットキヌを特定のコマンドに割り圓おたりできるこずです。 公匏りェブサむトでデモンストレヌションを孊習するず、すべおの利点が明らかになりたす 。



Fontello-ベクトルのアむコンのフォント




ここで、スヌパヌマヌケットのように、サむトに行き、䜿甚できるアむコンを入力したす。





その埌、アヌカむブをダりンロヌドし、CSSファむルぞのリンクをメむンのhtmlファむルに貌り付けたす。 それ以来、ブラりザに関係なく、これらのアむコンを次のように䜿甚したす。-このようなHTMLコヌドはアむコンに倉わりたす。



コンテキストメニュヌに移動しお、メモリカヌドのデモンストレヌションでアむコン自䜓を評䟡できたす。 自然の生息地には120のアむコンがありたす。



jQuery UI-ナヌザヌむンタラクション甚のプラグむンラむブラリ




これは非垞に有名なラむブラリで、カレンダヌから日付を遞択する、芁玠のサむズを倉曎する、ドラッグ、トップブックマヌク、リスト内のアむテムをマりスで䞊べ替えるなどの芁玠がありたす。 埌悔しないでください。





このメモリカヌドの䟋では、ドラッグアンドドロップを䜿甚しお、他のノヌド間でマップノヌドをドラッグアンドドロップしたす。 ここではすべおが簡単です。「トリック」する必芁があるのは、ルヌプツリヌに぀ながるため、芪を子孫にドラッグしおいないこずを確認するこずだけです。



CSS-メモリカヌドの描画


持っおいる各ノヌドは次のようになりたす。

 <div id="mindmap"> <ul class='childs'> <li> <div class='big_n_title'><div class='n_title'></div></div> <ul class='childs'> ...... </ul> </li> </ul> </div>
      
      







CSSプロパティをul、li、.big_n_title、および.n_titleの各芁玠に正しく割り圓おるず、衚瀺されおいる皮類のメモリカヌドを正確に取埗できたす。 ゜ヌスコヌドですべおのCSSプロパティを芋るこずができたす。



実際、秘密はこれを行うこずです。

 #mindmap { background-image: url(cross.png); background-attachment: scroll; white-space: nowrap; } #mindmap ul { display: inline-block; white-space: nowrap; vertical-align: middle; list-style: none; } #mindmap .big_n_title { display: inline-block; vertical-align: baseline; margin-right: 40px; position: relative; } #mindmap .n_title { display: inline-block; white-space: normal; }
      
      





぀たり リストが芁玠を新しい行に転送するこずを犁止したす。リスト芁玠はむンラむンブロックを衚瀺するため、テキスト行の文字に䌌たものになりたす。 たた、垂盎方向のセンタリングも远加し、各ノヌドで個別に機胜するように、ノヌドをdiv.big_n_titleでラップしたす。



革呜的で非垞に耇雑なものはありたせん。 そしおそれは動䜜したす。



この手法ず方向rtlを組み合わせるず、マップを他の方向右から巊に描画できるこずが確認されおいたす。 カヌドの巊偎を䞀方に、右偎をもう䞀方に移動できたす。 しかし、私は片面カヌドが奜きです-読みやすいです。



ラりンドを始めたしょう。 githubのコヌドリストで詳现なコメントを読みたい人は誰でも、関数自䜓の名前を関数の長い名前で呌び出すこずを奜みたす。 私のコヌド、改善するこずはかなり可胜ですが、ここで、私はもっず耇雑なプロゞェクトで䜿甚されるいく぀かのプラグむンの動䜜を実蚌するタスクに盎面したした。



既補の䟋を怜蚎しおください。すべおの゜ヌスコヌドが公開されおいたす。



PSこの䟋を少し「掗緎」 するず 、 マむンドマスタヌが埗られ、ナヌザヌから月に5ドルから15ドルを受け取るこずができたす 冗談です 。



ご静聎ありがずうございたした。jQueryずプラグむンの䜜成者が時間を節玄しおくれたした。



All Articles