【99JS】之二:路径自动调整

上一篇,99给大家介绍了使用js控制“:nth-child()”的方法,今天99继续给大家介绍一个使用js自动调整路径的相关介绍,希望大家喜欢。

目标: 路径自动调整

需求是这样的:在javascript 开发中,常常会碰到相对路径与绝对路径的问题。而javascript模块化开发(补充javascript模块化http://www.cnblogs.com/muguaworld/archive/2011/11/27/2265356.html)。常见的实现方式就是把js文件按需载入,在载入的过程中也会遇到路径问题。比如我们有路径/workspace/wwwroot/module1;我们需要加载 wwwroot下面的a.js文件,跟wwwroot下面module2的b.js文件,熟悉linux的同学就会知道 当目录/workspace/wwwroot/module1,我们输入 ../a.js 即可以拿到文件,此时的路径为/workspace/wwwroot/a.js,我们输入../module2/b.js 此时的路径为/workspace/wwwroot/module2/b.js而javascript语言是浏览器端语言,除了现代浏览器未实现完全的fileapi外,他是不能操纵任何文件的。

补充 fileapi 跟 javascript安全策略 (沙箱策略)

  1. 沙箱策略http://hi.baidu.com/meklrdoxtkbkyzd/item/c2480ad3f64e0848fa57684e
  2. 同源策略http://baike.baidu.com/view/3747010.htm

html5file api

  1. https://developer.mozilla.org/en-US/docs/DOM/File_API
  2. https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

以及我写的fileapi的一个小应用:上传后预览http://99jty.com/?p=856

扯了那么多,我们来抽象成需求

  1. 设str = 'aa/bb/cc' 设用户输入user = '../dd.js';
  2. 则返回 aa/bb/dd.js

思路1

我们分析一下路径的组成

aa/bb/cc ../dd.js > aa/bb/dd.js
aa/bb/cc ../../dd.js > aa/dd.js

可以很清楚的看到:str的总长度- ..的个数 就是str需要保留的路径。那么我们只需要统计下 ../的个数就是了。。。

实现1:

function adjustPath(str, user) {
  var strArr = str.split("/"),
  userArr = user.split("../");
  var sl = strArr.length,
  ul = userArr.length;
  var s = "";
  var l = sl - ul;
  if (l < 0)
    throw new Error('未找到文件!')
    for (var i = 0; i < l; i++) {
      console.log(i, strArr[i]);
      s += strArr[i] + "/";
    }
  return s + userArr[userArr.length - 1];
}
var str = 'aaa/bbb/ccc/'
console.log(adjustPath(str, '../../../../dd.js'))

split方法是非常有用的一个东东,可以把字符串转成数组,另外 join方法是他的逆运算。这里给大家讲个技巧:

当涉及 字符串单字符,或者有规律的分隔符的字符串,尝试用split切分成数组,会好处理很多。关于字符串与数组的一系列方法。。属于js核心中的核心,希望背熟。。。http://www.w3cschool.cn/js_reference.html

第二个要讲的是throw new Error 这个命令。

在程序设计中,很重要的一点就是“容错性”, 也就是程序是否能够在遇到错误的时候进行相应的处理。我们可以观察到,当..数量太多,就不会找到文件了,这时候进行下一步操作,会严重影响程序的返回结果。所以我们if判断一下, 若出现问题,则抛个错。 在java开发中这应该是经常用的吧~其他其实也不用讲了,第一个思路比较简单。

思路2

涉及字符串的大部分问题都可以用正则表达式直接解决。这里我们要利用一个正则表达式的小技巧 吐泡泡- -

var d = [1, 2, 3, 4, 5];
var b = 'abcakjabjsaabadab';
var nstr = b.replace(/ab/g, function (a) {
  console.log(a);
  return d.pop() ? "" : 'hahah';
})

先解释一下吧replace方法是string对象的方法,可以替换字符串或者正则。而替换的时候可以传入一个参数function 这个function很有意思,它的参数包含被前面正则所“匹配”的部分。 详细的话,可以见replace的参考http://www.w3school.com.cn/js/jsref_replace.asp,跟我写的 function传参~http://99jty.com/?p=470

另外补充下 正则表达式也推荐看看这一篇:http://www.cnblogs.com/rubylouvre/archive/2010/03/09/1681222.html正美的大作,基本把我们常用的都概括了。我们回到函数,以上函数返回的结果很有意思,返回了四个ab (显然是b匹配上四个ab字符串).但是呢,d变成了1。。。。这是肿麽回事呢。。我认为,每匹配一次,都会执行replace里面传的function函数一次,因此d就pop的没了。。。我把这个函数叫做。。正则吐泡泡。。。那这个与我们那个题目有啥关系呢。。。。聪明的人应该想到了,首先把字符串弄成数组形式

aa/bb/cc > [aa,bb,cc]

每次发现一个../我们就删掉字符串末尾的一项。比如 ../dd.js 那么 删掉后变为 [aa,bb] 之后组合起来就是我们想要的答案了~

实现:

function adjustPath(str, user){
  var patharr = str.replace(/\/$/,"").split("\/");
  console.log(str.replace(/\/$/,"").split("\/"));
  var nstr = user.replace(/\.\.\//g,function(a){console.log(a);
  return patharr.pop() ? "" : a;
});
  console.log(nstr,patharr);
  return patharr.length ? patharr.join("/")+"/"+nstr : nstr;
}
console.log('aa/bb/cc','../dd.js')

以上函数呢可能正则大家会看得比较晕。这里稍微解释下:

  1. \符号是转义的意思。当需要匹配的内容包含
  2. ^ $ . * + ? = ! : | \ / ( ) [ ] { } 时,需要用 \ 转义。

比如我们想匹配 ../ 会发现三个都需要转义。。那么就要写成 \.\.\/而每个正则表达式是由一个// 包裹起来的,我们包裹起来 /\.\.\//在函数中,还写了一个 patharr.pop() ? "" : a 他是javascript的三目表达式。其实很简单:a?b:c的意思是:

if(a){b}
else{c}

今天的你整明白了吗?要是没有整明白我们可以一起探讨。之后补充其他的方法!!!!!!!!!!!!欢迎本专栏相关更新。

如需转载,烦请注明出处:http://www.w3cplus.com/js/99js-automatic-adjustment-path.html

返回顶部