以下是一个简单的 HTML + CSS + JS 实现登录注册界面的示例代码:
HTML 部分:
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录注册title>
<link rel="stylesheet" href="styles.css">
head>
<body>
<div class="container">
<div class="form-container sign-in-container">
<form action="#">
<h1>登录h1>
<input type="text" placeholder="用户名" id="loginUsername" required>
<input type="password" placeholder="密码" id="loginPassword" required>
<button type="submit" onclick="login()">登录button>
form>
div>
<div class="form-container sign-up-container">
<form action="#">
<h1>注册h1>
<input type="text" placeholder="用户名" id="registerUsername" required>
<input type="password" placeholder="密码" id="registerPassword" required>
<input type="password" placeholder="确认密码" id="confirmPassword" required>
<button type="submit" onclick="register()">注册button>
form>
div>
<div class="overlay-container">
<div class="overlay">
<div class="overlay-panel overlay-left">
<h1>欢迎回来!h1>
<p>请登录使用您的账户p>
<button class="ghost" id="signIn">登录button>
div>
<div class="overlay-panel overlay-right">
<h1>你好,新朋友!h1>
<p>输入您的详细信息开始使用p>
<button class="ghost" id="signUp">注册button>
div>
div>
div>
div>
<script src="script.js">script>
body>
html>
CSS 部分(styles.css):
body {
font-family: 'Arial', sans-serif;
background-color: #f6f5f7;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
position: relative;
overflow: hidden;
width: 768px;
max-width: 100%;
min-height: 480px;
}
.form-container {
position: absolute;
top: 0;
height: 100%;
transition: all 0.6s ease-in-out;
}
.sign-in-container {
left: 0;
width: 50%;
z-index: 2;
}
.sign-up-container {
left: 0;
width: 50%;
opacity: 0;
z-index: 1;
}
.overlay-container {
position: absolute;
top: 0;
left: 50%;
width: 50%;
height: 100%;
overflow: hidden;
transition: transform 0.6s ease-in-out;
z-index: 100;
}
.overlay {
background: #ff416c;
background: -webkit-linear-gradient(to right, #ff4b2b, #ff416c);
background: linear-gradient(to right, #ff4b2b, #ff416c);
background-repeat: no-repeat;
background-size: cover;
background-position: 0 0;
color: #fff;
position: relative;
left: -100%;
height: 100%;
width: 200%;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
}
.overlay-panel {
position: absolute;
top: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0 40px;
height: 100%;
width: 50%;
text-align: center;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
}
.overlay-left {
transform: translateX(-20%);
}
.overlay-right {
right: 0;
transform: translateX(0);
}
.container.right-panel-active.sign-in-container {
transform: translateX(100%);
}
.container.right-panel-active.sign-up-container {
transform: translateX(100%);
opacity: 1;
z-index: 5;
}
.container.right-panel-active.overlay-container {
transform: translateX(-100%);
}
.container.right-panel-active.overlay {
transform: translateX(50%);
}
.container.right-panel-active.overlay-left {
transform: translateX(0);
}
.container.right-panel-active.overlay-right {
transform: translateX(20%);
}
input {
background-color: #eee;
border: none;
padding: 12px 15px;
margin: 8px 0;
width: 100%;
border-radius: 5px;
}
button {
border-radius: 20px;
border: 1px solid #ff4b2b;
background-color: #ff4b2b;
color: #fff;
font-size: 12px;
font-weight: bold;
padding: 12px 45px;
letter-spacing: 1px;
text-transform: uppercase;
transition: transform 80ms ease-in;
cursor: pointer;
}
button:active {
transform: scale(0.95);
}
button:focus {
outline: none;
}
button.ghost {
background-color: transparent;
border-color: #fff;
}
JavaScript 部分(script.js):
function login() {
const username = document.getElementById('loginUsername').value;
const password = document.getElementById('loginPassword').value;
// 这里可以添加登录验证逻辑,例如发送请求到服务器进行验证
console.log(`用户名: ${username}, 密码: ${password}`);
alert(`登录成功!用户名: ${username}`);
event.preventDefault();
}
function register() {
const username = document.getElementById('registerUsername').value;
const password = document.getElementById('registerPassword').value;
const confirmPassword = document.getElementById('confirmPassword').value;
if (password!== confirmPassword) {
alert('密码和确认密码不一致,请重新输入。');
return;
}
// 这里可以添加注册逻辑,例如发送请求到服务器进行注册
console.log(`注册新用户:用户名: ${username}, 密码: ${password}`);
alert(`注册成功!用户名: ${username}`);
event.preventDefault();
}
document.getElementById('signUp').addEventListener('click', () => {
document.querySelector('.container').classList.add('right-panel-active');
});
document.getElementById('signIn').addEventListener('click', () => {
document.querySelector('.container').classList.remove('right-panel-active');
});
代码解释:
HTML 部分:
CSS 部分:
JavaScript 部分:
使用方法:
1. 将上述 HTML 代码保存为index.html文件。
2. 将 CSS 代码保存为styles.css文件,并确保在 HTML 中正确引用:。
3. 将 JavaScript 代码保存为script.js文件,并确保在 HTML 中正确引用:。
4. 打开index.html文件,在浏览器中查看登录注册界面。
这个示例提供了一个简单的登录注册界面基础,你可以根据需要添加更多功能,例如:
请注意,在实际应用中,你需要对用户输入进行更严格的验证和处理,同时需要考虑安全性问题,例如对密码进行加密存储和传输,防止跨站脚本攻击(XSS)和 SQL 注入攻击等。 此外,你可能需要使用服务器端语言(如 Node.js、PHP、Python 等)和数据库(如 MySQL、MongoDB 等)来处理用户的登录注册信息。 上述代码仅为前端部分,主要用于展示界面和基本交互逻辑。
这个登录注册界面使用了 HTML 进行结构搭建,CSS 进行样式设置,JavaScript 进行交互逻辑处理,通过简单的动画效果和表单操作实现了登录和注册的切换以及基本的用户输入处理。你可以根据自己的需求对其进行扩展和修改,以满足更复杂的业务需求。
初审:沈巧梅 复审:茉莉 终审:海棠
【JS应用】Iframe 解决跨域
天气降温,大家注意保暖~~~
因为学习了腾讯出的前端进阶课程,所以打算把课程内容都总结一遍。有些都是很普通很常见的知识,但是为了巩固自己的知识面,梳理自己的知识树,所以每个知识点都会写成文章,所有文章都会放在公众号右下角的前端进阶课程总结中~~~也希望能够帮助到需要的人~~
跨域的东西,简直不要接触太多,网上相关内容一抓一大把,但是突然学习到一个关于前端解决跨域的方式
就是 利用iframe
不管你有没有了解过,反正我没有
我觉得很有用并且容易忘,所以我记录下来哈哈哈
下面会分三块内容进行描述
1、基本原理
2、简单模拟
2、封装的函数
3、封装函数实战
解决场景
现在我们在a.com的域名下有一个页面
我们要请求b.com下的一个接口,很明显是会跨域的,无法直接请求
今天我们使用iframe来解决这个问题
基本原理
1、需要三个页面
两个同域(a.com)的页面,一个和接口同域的页面(b.com)
其中一个页面是父页面,也就是真正的内容页,展示数据的
另外两个作为子页面,是辅助父页面请求跨域数据用的,不会显示在页面中
2、利用全局变量 window.name存储数据
父子页面利用 window.name 进行通信,但是前提是同域
当父子页面不同域的时候,父子无法访问对方 window.name
但是,如果是同级页面切换,就算是不同域,window.name 也是可以访问的
3、数据请求
现在请求b.com的接口,所以只能在b.com下的页面(这个是子页面)进行请求
请求成功后,保存在当前的window.name中
4、页面跳转
上一步保存完数据之后,由b.com页面 跳到a.com页面
此时a.com页面就能通过window.name拿到b.com 保存过的数据啦
5、给父页面传递数据
上面那个a.com页面是辅助页,拿到数据之后,需要传递给真正需要数据的父页面(同样是a.com下)
大概了解之后,我们来说一下简单流程
现在有a.com下的内容页A,需要请求接口 b.com/xxxx,但是跨域
1、内容页 A 嵌入一个隐藏 iframe,iframe加载b.com下的辅助页面B
2、辅助页面B开始请求接口b.com/xxx,请求成功,存放到window.name
3、隐藏 iframe由页面B跳转到a.com下另一个辅助页(页面C)
4、页面C读取到B存放的window.name,然后传递给父页面A
5、父页面A拿到数据,用于展示在页面上
简单模拟
现在我启动了两个服务
1、localhost:3001下有 a.html和c.html
a.html是内容页,需要使用数据的终端页(以下简称A)
c.html是辅助页(以下简称C)
2、localhost:3002下有b.html
b.html也是辅助页,用于请求数据(以下简称B)
内容页 A
在A中,使用iframe 嵌入了B,并且全局设置了一个函数getData
这个函数的作用是,为了给C页面调用,传入接口的数据的
<body>
我是A页面
<script>
window.getData=function(data){
console.log("获取到数据",data)
}
script>
<iframe src="http://localhost:3002/b.html" >iframe>
body>
辅助页 B
B页面当然是用于请求接口了,这里使用定时器模拟接口,请求成功后跳转到C
<body>
我是B页面
<script>
console.log("B页面开始请求接口")
setTimeout(function(){
window.name="我是B页面保存的数据"
location.href="http://localhost:3001/c.html"
},2000)
script>
body>
辅助页C
B请求完,跳到C之后,C拿到window.name,然后调用A的方法getData,并且把数据传过去
<body>
我是C页面
<script>// 调用页面A 的方法,并把 name 传过去
parent.getData(window.name)
script>
body>
没错,这就完成了iframe解决跨域的问题,但是实际上并不会这么做,肯定是封装得更加适用一些
详情就看下面吧
封装函数
经过上面的说明,我们首先要明确我们的目的
1、iframe
2、两个辅助页
3、数据回调
所以我们封装的函数必须要满足这几个东西
首先,封装一个函数创建iframe插入body中,并且转到传入的 url
function createIframe (url) {
var doc = document
var iframe = doc.createElement('iframe')
iframe.src = url
iframe.frameborder = '0'
iframe.style.display = 'none'
doc.body.appendChild(iframe)
}
很简单,都能看懂
之后,我们需要在url上拼接参数,所以我们需要在封装一个url相关的函数
为什么需要拼接参数?
比如请求的接口需要某些参数,这些参数是父页面提供的,所以就只能把这些参数放到iframe的url上以便通信
拼接url 函数
function parseUrl (url, param) {
return url + (url.indexOf('?') === -1 ? '?' : '&') + serialize(param)
}
当时放在url上的参数,是要经过转义的,比如不能出现中文,所以需要多一个函数用于格式化参数
function serialize (data) {
var ret = []
Object.keys(data).forEach(item => {
ret.push(encodeURIComponent(item) + '=' + encodeURIComponent(data[item]))
})
return ret.join('&')
}
那么现在就万事俱备,只欠主菜了,马上来看
function cross (option, callback) {
var funcName = getFunctionName()
var data = option.data || {}
window[funcName] = function (response) {
callback(response)
window[funcName] = null
}
var url = parseUrl(option.targetUrl, {
data:option.data,
url:option.url,
parentFuc:funcName,
skipUrl:option.skipUrl
})
createIframe(url)
}
在这个函数中,解决了我们一开始提到的两个问题
1、数据回调
2、两个辅助页
很明显,这个函数是给我们的父页面调用的啦
首先,cross函数接收两个参数,options和callback,一个个解释
options
是一个对象,包含下面四个字段
targetUrl
用于请求接口,跟接口同域那个辅助子页面
skipUrl
请求接口成功后,跳转到的那个子页面
data
请求接口时需要传递的参数
url
需要进行请求的接口名
callback
很明显,这个回调,也就是接口请求完成,跳转完成之后会触发的
但是并不是直接触发,而是包装了一层,你看其中这段
var funcName = getFunctionName()
window[funcName] = function (response) {
callback(response)
}
主要作用还是像我们模拟中的一样,在父页面中注册一个函数,给子页面传递数据用
但是这个函数注册就有点意思了,因为是全局的,非常害怕全局污染和重名,所以这里弄了一个随机生成函数名的函数getFunctionName,如下
function getFunctionName () {
return ('iframe_' + Math.random())
.replace('.', '')
}
但是,函数名是随机的,子页面怎么知道我要调用那个函数?
子页面:我不知道函数名字啊!!!!
所以需要把函数名字也传递
怎么传递?
放到url上,然后子页面就可以直接从url上拿参数,并取其中的字段 parentFunc ,就可以知道函数名啦
优化
随着请求越来越多,生成的全局随机函数肯定会越来越多,并且是一次性的,不会再被使用,留着根本没用,还占用资源
所以我们最好手动清除他,所以你看到在设置全局函数时,回调执行完之后就执行设置为null
window[funcName] = function (response) {
callback(response)
window[funcName] = null
}
没错,封装的函数我们已经看完了,我们还是有必要来看下怎么使用的啊
封装函数的实践
在这里我先出一个大王函数,用于获取链接参数的,直接得到对象的
作用如下
然后就到我们的正文了
首先,我们的内容页率先登场,并且调用cross表示调用接口
<body>
<script>
cross({
// 请求数据的页面
targetUrl: 'http://127.0.0.1:3002/b.html',
// 当区域跳转的页面
skipUrl: 'http://127.0.0.1:3001/c.html',
// 需要请求的接口
url:"http://localhost:3002/getUserInfo"
data: {} // 参数
}, data= >{
console.log("接收到数据",data)
});
});
script>
body>
接着,到了我们要请求接口的B页面
拿到 url上的请求接口和请求参数,调用ajax
调用成功后,拿到url上的跳转链接skipUrl,直接跳过去,并且带上参数parsetFunc
因为C页面中,需要知道函数名,所以这里必须带上
<body>
<script>
var param = parseQueryString(location.href)
ajax({
url:${param.url},
data:${param.data},
success(data){
// 数据保存在 window.name
window.name = data
// 跳转到父页面配置的子页面,并且把配置的函数名带上
location.href = `${param.skipUrl}?parentFunc = ${param.parentFunc}`;
}
})
script>
body>
那么现在就只剩下我们的C页面了
从url上获取到函数名,然后拿到父页面的window(也就是parent)
直接调用,并且传入window.name
这样,整个流程就走完了
<body>
<script>
var param = parseQueryString(location.href)
parent[param.parentFuc](window.name);
script>
body>
不过说真的,这种方法也就作为一个备胎方法,大家熟悉熟悉知道一下就好了,毕竟项目中也不太可能用到
不过面试可能会问哈哈,多掌握点总是没错的
最后
鉴于本人能力有限,难免会有疏漏错误的地方,请大家多多包涵,如果有任何描述不当的地方,欢迎后台联系本人,领取红包