遇到一个有趣需求,需要将页面内的一些链接按照规则判断是否需要打开新的窗口或使用已存在的窗口,如:当前存在的链接格式为?www.autohome.com.cn/[path]/[x].… , 当path相同时,使用已存在的窗口打开新的页面,否则打开新的窗口。1.使用?window.open?打开新的窗口window.open 是我们熟知打开新的窗口的方法。open(url, target, windowFeatures) 方法第一个参数url是要打开的URL,第二个参数?target?是窗口的名字,第三个参数?windowFeatures?是窗口的属性。更多信息查看MDN:
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/open1.1?target参数target 一个不含空格的字符串,用于指定加载资源的浏览上下文的名称。如果该名称无法识别现有的上下文,则会创建一个新的上下文,并赋予指定的名称。还可以使用特殊的 target 关键字:_self、_blank、_parent 和 _top。该名称可用作 或 元素的 target 属性。 1const?article?=?[{ 2title:?'A?路径?/?1.html', 3path:?'https://www.autohome.com.cn/A/1.html', 4},?{ 5title:?'B?路径?/?1.html', 6path:?'https://www.autohome.com.cn/B/1.html', 7},?{ 8title:?'A?路径?/?2.html', 9path:?'https://www.autohome.com.cn/A/2.html',10},?{11title:?'B?路径?/?2.html',12path:?'https://www.autohome.com.cn/B/2.html',13}]1415export?default?function?App()?{16return?(1718{article.map((item)?=>?{19return?(20?{23{/*?window.open?的第二个参数?target?将会为?"A"?或?"B"?*/}24window.open(item.path,?new?URL(item.path).pathname.split('/')?.[1])25}}26>27{item.title}2829);30})}3132);33}分别点击以上的链接,我们会发现,当点击第一个和第三个链接时,会在同一个窗口打开页面,而点击第二个和第四个链接时,会在同一窗口打开新的页面。点击上面所有链接后,我们会发现,浏览器只新打开了两个窗口。这样做还有一些缺陷,继续探究...2.使用标签打开新的窗口使用?window.open?会对SEO(搜索引擎优化)有一些影响,因为使用?window.open?打开的页面,搜索引擎不会对其进行抓取。所以我们期望可以使用标签的?target?属性来打开新的窗口。2.1标签的?target?属性我们熟知的 标签的 target 属性有以下几个值:_self 默认值,当前窗口打开_blank 新窗口打开_parent 父窗口打开_top 顶层窗口打开在 MDN 中介绍 windown.open 中的 target 参数中我们可以看到 target参数名称可用作 或 元素的 target 属性, 标签的 target 同window.open 的 target 参数一样,可以指定一个窗口的名字。 1const?article?=?[{ 2title:?'A?路径?/?1.html', 3path:?'https://www.autohome.com.cn/A/1.html', 4},?{ 5title:?'B?路径?/?1.html', 6path:?'https://www.autohome.com.cn/B/1.html', 7},?{ 8title:?'A?路径?/?2.html', 9path:?'https://www.autohome.com.cn/A/2.html',10},?{11title:?'B?路径?/?2.html',12path:?'https://www.autohome.com.cn/B/2.html',13}]1415export?default?function?App()?{16return?(1718{article.map((item)?=>?{19return?(202328{item.title}293031);32})}3334);35}结果是可喜的,符合所有预期结果。还没完>>>封装成一个组件接下来我们考虑将这个功能封装成一个组件。解决一下?target="A"?或?target="B"?属性暴露以及target生成方法优化。 1//?简单的封装 2export?default?function?ALink(props:?{ 3children:?React.ReactNode; 4href:?string; 5[key:?string]:?any; 6})?{ 7const?{?children,?href,?target?=?'_self'?}?=?props; 8return?( 9?{13e.preventDefault();14if(target?!=?'_blank')?{15window.open(href,?target);16}?else?{17window.open(href,?new?URL(href).pathname.split('/')?.[1]);18}19}}20>21{children}2223);24} 1//?使用 2import?ALink?from?'./ALink'; 3 4const?article?=?[{ 5title:?'A?路径?/?1.html', 6path:?'https://www.autohome.com.cn/A/1.html', 7},?{ 8title:?'B?路径?/?1.html', 9path:?'https://www.autohome.com.cn/B/1.html',10},?{11title:?'A?路径?/?2.html',12path:?'https://www.autohome.com.cn/A/2.html',13},?{14title:?'B?路径?/?2.html',15path:?'https://www.autohome.com.cn/B/2.html',16}]1718export?default?function?App()?{19return?(2021{article.map((item)?=>?{22return?(232630{item.title}313233);34})}3536);37}感兴趣的同学 去试试吧>>>