QQ登录面板

最近在慕课网学习DOM事件的基础知识,有个任务是让实现QQ面板拖拽效果,于是想先自己先写写再去看老师的代码。发现,其实自己一步一步写会收获很大。以下是QQ登录面板的具体实现(图片是下载老师现成的,haha,不过代码都是自己的,自学的初级阶段,有错请多多指教)。

效果图

QQ登录面板
QQ登录面板

具体要求
  • 看着老师的效果自己揣测的→_→*
  • 用HTML/CSS实现基本的布局和样式,JS实现简单的交互
  • 点击关闭按钮,关闭QQ登录面板
  • 可以切换登陆时的状态
  • 当mousedown在 QQ logo 区域并移动时,面板随鼠标移动
实现
  • HTML部分
    <div id="QQLoginSurface">
        <div id="closeBox"></div>
        <div id="LoginIcon"></div>
        <div id="QQLogin">
            <div id="countNumber">
                <span id="countNumberText"><b>账&#9;号:</b>&nbsp;</span>
                <input type="text" placeholder="QQ号码或Email账号" id="inputCountNumber"/>
            </div>
            <div id="countPassword">
                <span id="countPasswordText"><b>密&#9;码:</b>&nbsp;</span>
                <input type="password" id="inputCountPassword" />
            </div>
        </div>
        <div id="loginButton"></div>
        <div id="loginState" title="选择登录状态">
            <span id="loginStateIcon" class="onlineImage"></span>
            <span id="loginStateDropdownButton"></span>
            <span id="loginStateText">我在线上</span>
        </div>
        <ul id="stateBox">
            <li class="differentState" data-text="我在线上 0">
                <span class="differentStateImage onlineImage" id="online"></span>
                <span>我在线上</span>
            </li>
            <li class="differentState" data-text="离开 18">
                <span class="differentStateImage awayImage" id="away"></span>
                <span>离开</span>
            </li>
            <li class="differentState" data-text="忙碌 36">
                <span class="differentStateImage buzyImage" id="buzy"></span>
                <span>忙碌</span>
            </li>
            <li class="differentState" data-text="隐身 54">
                <span class="differentStateImage invisibleImage" id="invisible"></span>
                <span>隐身</span>
            </li>
            <li class="differentState" data-text="Q我吧 72">
                <span class="differentStateImage callMeImage" id="callMe"></span>
                <span>Q我吧</span>
            </li>
            <li class="differentState" data-text="离线 90">
                <span class="differentStateImage offlineImage" id="offline"></span>
                <span>离线</span>
            </li>
            <li class="differentState" data-text="请勿打扰 108">
                <span class="differentStateImage leaveMeImage" id="leaveMe"></span>
                <span>请勿打扰</span>
            </li>
        </ul>
    </div>
  • CSS部分
body {
    margin: 30px;
    font-family: 'Microsoft YaHei';
    -webkit-user-select: none;
    -ms-user-select: none;
    -moz-user-select: none;
    user-select: none;
    /*去掉双击选中*/
}

span {
    display: inline-block;
    font-size: 13px;
}

input,button {
    outline: none;
    /*去掉聚焦边框*/
}

ul {
    list-style: none;
}

#QQLoginSurface {
    width: 380px;
    height: 250px;
    background-color: rgb(246, 246, 246);
    border-radius: 0.5em;
     box-shadow:0 0 3px 3px rgba(0,0,0,0.4);
}

#closeBox {
    margin: 0;
    width: 28px;
    height: 28px;
    background: url(../images/boxy_btn.png);
    position: relative;
    left: 362px;
    top: -10px;
}

#closeBox:hover {
    cursor: pointer;
}

#LoginIcon {
    width: 200px;
    height: 44px;
    background: url(../images/login_window_logo.png);
    background-position: 200px 0;
    margin: -14px auto;
}

#LoginIcon:hover {
    cursor: move;
}

#QQLogin {
    width: 240px;
    margin: 40px auto;
    margin-bottom: 10px;
    text-align: center;
}

#countNumberText,#countPasswordText {
    font-size: 16px;
}

#inputCountNumber {
    padding: 1px;
    padding-left: 8px;
    border: 1px rgba(0,0,0,0.2) solid;
    height: 20px;
    line-height: 18px;
    border-radius: 10px;
}

#inputCountPassword {
    padding: 1px;
    padding-left: 8px;
    border: 1px rgba(0,0,0,0.2) solid;
    height: 20px;
    line-height: 18px;
    border-radius: 10px;
    margin-top: 20px;
}

#loginButton {
    display: inline-block;
    width: 110px;
    height: 35px;
    background: url(../images/login_btn.png) no-repeat;
    background-position: -112px -1px;
    margin-left: 80px;
    margin-top: 10px;
}

#loginButton:hover {
    cursor: pointer;
}

#loginState {
    display: inline-block;
    position: relative;
    left: 15px;
    top: -8px; 
}

#loginState:hover {
    cursor: pointer;
}

#loginStateIcon {
    width: 18px;
    height: 18px;
    background: url(../images/ptlogin.png);
}

#loginStateDropdownButton {
    width: 18px;
    height: 18px;
    background: url(../images/ptlogin.png);
    background-position: 0 -18px;
}

#loginStateText {
    width: 60px;
    height: 18px;
    position: relative;
    top: -5px;
    left: -10px;
}

#stateBox {
    width: 100px;
    background-color: white;
    padding: 5px; 
    margin: -18px 0 0 205px;
    position: relative;
    z-index: 1;
    box-shadow: 1px 1px 1px rgba(0,0,0,0.2);
    display: none;
}

#stateBox>.differentState {
    padding-left: 5px;
}

#stateBox>.differentState:hover {
    cursor: pointer;
    background-color: rgb(128, 128, 128);
}

.differentStateImage {
    background: url(../images/ptlogin.png) no-repeat;
    width: 18px;
    height: 18px;
}

.onlineImage {
    background-position: 0 4px;
}

.awayImage {
    background-position: -18px 4px;
}

.buzyImage {
    background-position: -36px 4px;
}

.invisibleImage {
    background-position: -54px 4px;
}

.callMeImage {
    background-position: -72px 4px;
}

.offlineImage {
    background-position: -90px 4px;
}

.leaveMeImage {
    background-position: -108px 4px;
}

-JS部分

//关闭QQ登录面板
var QQLoginSurface = document.getElementById("QQLoginSurface");
var closeBox = document.getElementById("closeBox");
closeBox.addEventListener("click", function () {
    QQLoginSurface.style.display = "none";
},
false);

//光标聚焦时, input的提示语句消失, 失焦时, input的提示语句再次出现
var inputCountNumber = document.getElementById("inputCountNumber");
inputCountNumber.addEventListener("focus", function () {
    inputCountNumber.placeholder = "";
},
false);

inputCountNumber.addEventListener("blur", function () {
    inputCountNumber.placeholder = "QQ号码或Email账号";
},
false);

//点击loginState后, stateBox列表出现
var loginState = document.getElementById("loginState");
var stateBox = document.getElementById("stateBox");
loginState.addEventListener("click", function () {
    stateBox.style.display = "block";
}, false);

//选中ul中的状态,改变登录状态
var loginStateText = document.getElementById("loginStateText");
var loginStateIcon = document.getElementById("loginStateIcon");
stateBox.addEventListener("click", function (event) {
    var target = event.target || window.event.target;
    if (target.nodeName == "SPAN") {
        var trueTarget = target.parentNode;
        var dataText = trueTarget.getAttribute("data-text");
        var dataTexts = dataText.split(" ");
    } else if (target.nodeName == "LI") {
        var dataText = target.getAttribute("data-text");
        var dataTexts = dataText.split(" ");
    }
    loginStateText.innerHTML = dataTexts[0];
    loginStateIcon.style.backgroundPositionX = -Number(dataTexts[1]) + "px";
    stateBox.style.display = "none";
}, false);

//当stateBox的display属性为block时, 而紧接着的点击发生在非ul范围内时, display属性变为none
document.addEventListener("mousedown", function (event) {
        x = event.clientX,
        y = event.clientY
    var stateboxbounds = stateBox.getBoundingClientRect();
    if (stateBox.style.display == "block") {
        if (x < stateboxbounds.left || x > stateboxbounds.right || y < stateboxbounds.top || y > stateboxbounds.bottom) {
            stateBox.style.display = "none";
        }
    }
});

//让QQ面板在一定条件下随鼠标移动
var mouseDownPos;
var loginIcon = document.getElementById("LoginIcon");
loginIcon.addEventListener("mousedown", function (event) {
    mouseDownPos = {
        x: event.clientX,
        y: event.clientY
    };
});

document.addEventListener("mousemove", function (event) {
    var diffX = event.clientX - mouseDownPos.x;
    var diffY = event.clientY - mouseDownPos.y;
    QQLoginSurface.style.left = diffX + "px";
    QQLoginSurface.style.top = diffY + "px";
});

--让QQ面板在一定条件下随鼠标移动部分有bug,尽快修正--

果然代码是大爷,要好好伺候才行( •̀ ω •́ )y