浏览器有一个实用的功能,但是可能用的不多,就是书签/收藏夹的导入导出,因为现在大部分浏览器都有云同步功能,所以这个功能存在感不强。浏览器书签可以跨不同浏览器导入,也就是说导出的文件必须要有规范。我只是搜索了一下,一无所获。可能是各个公司制定的规范,没有官方标准。常见的数据交换格式有很多,比如xml、json、yaml,json应该是用的最多的,因为容易解析和存储,而且体积不大,很适合浏览器导出书签,但实际上,现代浏览器导出的书签文件是一个html文件。原因不明,也没有找到相关资料。我猜测原因可能是html文件对于普通用户来说比json更为熟悉。其次,html文件可以直接用浏览器打开。当然json文件也可以用浏览器打开,但直接点击可能会默认用文本编辑器打开。此外,它们在浏览器中以不同的方式呈现。html显示是一个普通的页面,上面有一堆超链接,有点难看。打开json有点类似于源码,不是很友好,因为一般用户导出书签在其他浏览器导入,所以屏蔽细节没有问题。html和xml类似,所以解析和传输也很简单。接下来看例子:基本结构如上,每个文件夹下都有一个书签。导出书签的源码如下:简要分析:1.标签字母全部大写2.DOCTYPE语句与普通HTML页面不同3.使用DL和DT组织书签。DL代表一个文件夹的内容列表,DT代表一个内容。它可能是书签或文件夹。如果有文件夹,就会有一个H3标签,用来表示书签名称。书签后面直接跟一个A标签,小写的p标签后面跟一个DL标签。有些标签没有关闭。4、H1标签前的一切与书签内容无关。5、文件文件夹名H3标签和超链接A标签都有ADD_DATE和LAST_MODIFIED保存时间信息。如果该属性不存在,则不影响6.文件夹名H3标签的属性PERSONAL_TOOLBAR_??FOLDER表示该文件夹下的内容是否显示在浏览器Toolbar中,否则默认放置在浏览器的其他文件夹中,但不一定,某些浏览器会有自己的行为。存在不影响html其实就是一个普通的字符串,所以可以手动生成。常见于一些导航网站和网址采集工具的导出功能,比??如各种导航(http://lxqnsys.com/d),有一点需要注意,就是html字符串一定要格式化带有换行符和缩进。下图压缩的不行:生成方式也很简单,书签是树状结构,递归循环拼接就可以了。先看书签数据的格式,忽略时间和图标:/是否是文件folderchildren:[{name:'',folder:true,children:[]},{name:'',//书签名称url:''//书签url}]}]如果你使用ES6,可以直接使用模板字符把字符串``换行拼接起来很方便:functioncreateBookmarksStr(bookmarks){letstr=` `letloop=(root)=>{letstr=''root.forEach((item)=>{if(item.folder){str+=` `str+=loop(item.children)str+=` `}else{str+=` `returnstr}ES6之前需要显式拼接换行符:functioncreateBookmarksStr(bookmarks){varstr='\n\n \n\t\t \n\t\t\t\t\t'varloop=function(root){varstr=''root.forEach(function(item){if(item.folder){str+=' \n\t\t\t\t\t\t\t\t'str+=loop(item.children)str+=' \n\t\t\t'}else{str+=' \n 'returnstr}看完了如何生成,我们来看看如何解析,解析和拼接类似,也是深度优先遍历,只是会有一些特征判断如何把一个字符串转成一棵树,最简单的方法就是先转成DOM元素,然后通过DOMAPI遍历。有一些库可以用来做这个,但是这里直接使用iframe:.style.display='none'//添加书签domstringiframe.contentWindow.document.documentElement.innerHTML=str//获取书签树的根节点returniframe.contentWindow.document.querySelector('dl')}functionanalysisBookmarksStr(str){letroot=getBookmarksStrRootNode(str)}查看转换结果:bookmarkDOMstring:转换后的DOM节点:获取书签树的根节点,然后递归遍历:functionwalkBookmarksTree(root){letresult=[]//深度优先遍历letwalk=(node,list)=>{letels=node.childrenif(els&&els.length>0){for(leti=0;i书签
${item.name}
书签
\n\n\t
\n\n\t\t\t\t
\n\t\t\t'+item.name+'
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t
