-
html里默认的meta viewpoint 在手机上用户可以双指放大页面,这个项目里不需要,可以去taobao.com复制它的meta。
-
给body加一个border,虽然边界不是页面的全部,但是给body加背景颜色的时候,浏览器会智能地把颜色扩展到整个页面。
border-radius: 4px;
border: 1px solid #ddd; /*输入框边界色,一种灰色*/
- icon使用:
symbol引用,使用步骤如下:
第一步:拷贝项目下面生成的symbol代码:
//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js 把它放在页面的js引用前边就可以
<script src="//at.alicdn.com/t/font_1710001_hyt1a74rpt9.js"></script>
第二步:加入通用css代码(引入一次就行):
<style type="text/css">
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style> //放到head里,css的引用前边就可以
第三步:挑选相应图标并获取类名,应用于页面:
<svg class="icon">
<use xlink:href="#icon-xxx"></use> //'-xxx'填图标的名字
</svg> //放到图标所在的位置就可以
- a标签的使用:
<a href="https://www.bilibili.com/">
<div class="site">
<div class="logo">
<img src="./images/bilibili.jpg" />
</div>
<div class="link">bilibili.com</div>
</div>
</a>
a标签是span元素,但是它可以包div,特例。但是a标签有默认的样式,会把页面变成这样:
a {
color: inherit;
text-decoration: none;
}
-
引入jQuery库,两种方法:1.下载jQuery代码
2.bootcdn:
把min.js那句代码放在script标签里,引入html。只要放在main.js那句代码前边就可以。 -
点击新增网站,弹出一个对话框“你要添加什么网址?”,在对话框里输入网址,然后通过jQuery创建一个li元素并且插入到页面里,也就是下方的方块。然后点击这个新增的网址,跳到相应页面,但是再次返回到原页面时,发现新增的那个方块消失了。怎么解决这个问题呢?
- 需要一个数据结构(hashMap数组),用于存储每个新增的网站。监听新增网站那个div,如果点击,先获取到用户输入的网址url,然后把对应的li元素的信息以对象的形式push进hashMap数组里,然后调用render函数(用于重新渲染页面,遍历hashMap,把hashMap里的所有对象插入到页面中)。
- 有了一个存储这些新增元素的数组,还是解决不了离开页面方块消失的问题。需要用到本地存储localStorage。
window.onbeforeunload = () => { //监听离开页面的事件 console.log("离开页面"); const string = JSON.stringify(hashMap); //localStorage只能存字符串,对象=>字符串 localStorage.setItem("x", string); //接收key,value的形式,把hashMap存在本地 }当监听到离开当前页面时,就把hashMap以键值对的形式存进localStorage里。当我再次回到当前页面时,读取localStorage里的值。
const x = localStorage.getItem("x"); //x目前还是字符串 const xObject = JSON.parse(x); //字符串=>对象在哪看localStorage?
localStorage会永久保留在浏览器中,关闭页面也不会消失,除非用户手动清除。localStorage的键值对只支持字符串。所以如果不是字符串的类型要存进localStorage里,比如对象,要使用JSON.stringify;把字符串转换成对象:JSON.parse。使用了hashMap数组存储li元素后,就可以不用在html里写li了,除了最后一个新增网站外,可以直接在JS里用render函数渲染初始的收藏网站。
const $siteList = $(".siteList"); const $last = $siteList.find(".last"); const x = localStorage.getItem("x"); //x目前还是字符串 const xObject = JSON.parse(x); //字符串=>对象 //用户第一次进来,初始状态,还没有新增时, //localStorage里是空,没有xObject,让hashMap等于初始的那些元素。 const hashMap = xObject || [ { logo: "A", logoType: "text", url: "https://www.acfun.cn/" }, { logo: "./images/bilibili.jpg", logoType: "image", url: "https://www.bilibili.com/" }, { logo: "./images/GitHub.png", logoType: "image", url: "https://github.com/" } ]; const render = () => { //渲染hash数组 $siteList.find("li:not(.last)").remove(); //在渲染之前,把之前的li删掉,避免重复 hashMap.forEach(node => { const $li = $(`<li> <a href="${node.url}"> <div class="site"> <div class="logo">${node.logo[0]}</div> <div class="link">${node.url}</div> </div> </a> </li>`).insertBefore($last); }); //遍历hashMap,先把之前的从页面删掉,再把所有的元素插入页面 }; render(); $(".addButton").on("click", () => { let url = window.prompt("你要添加什么网址?"); //url获取到用户输入的内容 //点击.addButton,弹出弹框 if (url.indexOf("http") === -1) { //window.prompt("请输入带有http的网址"); 用户体验不好 url = "https://" + url; } //如果用户输入的网址不带http,就自动为用户添加 hashMap.push({ logo: url[0], logoType: "text", url: url }); render(); }); window.onbeforeunload = () => { //监听离开页面的事件 console.log("离开页面"); const string = JSON.stringify(hashMap); //localStorage只能存字符串,对象=>字符串 localStorage.setItem("x", string); //接收key,value的形式,把hashMap存在本地 };现在页面的显示有一些问题,logo下方的link文本太长了,不需要前边的'https://www.',这一部分需要在render函数里通过jQuery创建元素时修改.link的文本值。原先是直接${node.url},即取全部url,现在要把url前边的http等删掉。利用字符串的replace方法。
const simplifyUrl = url => { //简化下边显示的link文本 return url .replace("https://", "") .replace("http://", "") .replace("www.", ""); };str.replace(substr,newstr) 查找str中的第一个substr子串,把它替换成newstr,返回新的字符串。如果str中没有substr,那就返回原字符串,即str。
同时还发现一个bug,如果用户输入的网址很长,如:'juejin.im/editor/post…', 那么显示在下方的文本也会很长,在删掉了前边的http://之后,我也不想要后边以/开头的内容。只显示'juejin.im'就可以。优化simplifyUrl函数:
const simplifyUrl = url => { //简化下边显示的link文本 return url .replace("https://", "") .replace("http://", "") .replace("www.", "") .replace(/\/.*/, ""); //正则表达式,删掉以/开头的内容 }; -
还需要一个功能:删除下方的网站。在每个li元素中,再加一个.close元素,实现点击方块右上角的close,就把这个方块删掉。
怎么实现?
在render函数里,遍历hashMap,创建li元素时,再增加一个.close子元素,里边包裹icon图标,在页面显示。(需要两个以上图标,重新生成代码,这句代码是所有图标的代码,直接在html里写这一句就可以<script src=''></script>)
问题1:因为.close元素还是在a标签里,所以点击它就相当于跳转到a标签。我需要用JS的阻止冒泡,stopPropagation(),使点击close时不触发a标签。
问题2:但是可能由于a标签太灵敏,不好用。所以我们不用a标签,用JS的click点击事件绑定每个li元素。在每次创建完li元素后,把该 $li 对象绑定一个点击事件:跳转到对应的页面。这里我们使用了window.open()
阻止冒泡后,开始绑定close自己的事件:点击close后,先阻止冒泡,然后把该close所在的li元素从hashMap里删除,再重新渲染render。
const render = () => { //渲染hash数组
$siteList.find("li:not(.last)").remove(); //在渲染之前,把之前的li删掉,避免重复
hashMap.forEach((node, index) => {
const $li = $(`<li>
<div class="site">
<div class="logo">${node.logo[0]}</div>
<div class="link">${simplifyUrl(node.url)}</div>
<div class='close'> <!--添加一个关闭图标-->
<svg class="icon">
<use xlink:href="#icon-close"></use>
</svg>
</div>
</div>
</li>`).insertBefore($last);
$li.on("click", () => window.open(node.url)); //新开一个窗口,用JS代替a标签。因为用a标签,阻止冒泡不好用
$li.on("click", ".close", e => {
e.stopPropagation(); //阻止冒泡,点击关闭时不跳转页面,不触发爸爸的事件
hashMap.splice(index, 1);
render();
});
});
};
PC端的宽度一般是固定的,就算拉小窗口,宽度也不会变,比如淘宝。