如何修复自定义警报功能

时间:2019-08-27 09:39:33

标签: javascript html css

我一直在尝试定制警报,这是到目前为止我要提出的:

window.CustomAlert = function(parameters) {
    var alert = document.createElement("div");
    var title = parameters.title !== undefined ? parameters.title : "ALERT!";
    var message = parameters.message !== undefined ? parameters.message : "Hello World!";
    var type = parameters.type !== undefined ? parameters.type : "";
    var color = type === "info" ? "#2196F3" : type === "success" ? 
        "#4CAF50" : type === "warning" ? "#ff9800" : type === "danger" ? "#f44336" : "#000000";
    document.body.appendChild(alert);
    alert.style.margin = "auto";
    alert.style.position = "absolute";
    alert.style.top = "0";
    alert.style.left = "0";
    alert.style.border = "1px solid black";
    alert.style.maxHeight = "350px";
    alert.style.width = "99.8%";
    alert.style.minHeight = "70px";
    alert.style.color = "white";
    alert.style.background = "#fff";
    alert.style.fontFamily = "sans-serif";
    alert.style.fontWeight = "bold";
    alert.style.overflow = "auto";
    alert.innerHTML = `
        <span style="float:right;font-size:25px;cursor:pointer;color:black;padding:7px;background:red" 
            onclick="this.parentElement.parentNode.removeChild(this.parentElement)"
        >&times;</span>

        //title
        <div style="background:` + color + `;padding:15px;height:30%">
            <p>` + title + `</p>
        </div>
        //message
        <div style="background:#ccc;padding:15px;height:80%">
            <p>` + message + `</p>
        </div>
    `;
};

CustomAlert({
    title: "LOG:",
    message: "Document initialized.",
    type: "info"
});

...那么将有3个问题: 1)标题和消息框之间会有一个烦人的间隙; 2)span功能仅关闭标题框;和 3)标题和消息的高度不起作用。 我该如何解决?

2 个答案:

答案 0 :(得分:0)

由于您似乎不熟悉JS,因此我将首先为您提供一些有关如何总体上改进代码的指针:

  • 将CSS用于警报样式,请勿使用内联样式。它在您的代码中添加了太多行
  • 将警报类型定义为类似枚举的对象:

    const CustomAlertType = {
        info: {color:"#2196F3"},
        success: {color:"#4CAF50"},
        warning: {color:"#ff9800"},
        danger: {color:"#f44336"},
        defaultValues: {color:  "#000000"}
    }
    
  • 由于您正在使用字符串模板,因此可以执行以下操作:value=${variable}
  • 在设置alert之前,请勿添加innerHTML。它对浏览器有影响,因为它需要验证DOM树。为此,除非需要,请尝试不要使用innerHTML
  • 请勿在HTML中使用像这样的回调:<elm onclick=...,而是可以这样做:alert.querySelector("span.close").addEventListener("click",。之后,HTML缩小很多,更易于阅读:

    alert.innerHTML = `
        <span class="close">&times;</span>
        <div class="title" style="background:${typeObj.color};">
            <p>${title}</p>
        </div>
        <div class="message">
            <p>${message}</p>
        </div>
    `;
    
  • 关闭警报时,您可能应该有一个回调。 parameters.onclose
  • 作为一种特殊待遇,我添加了一个示例如何在异步函数中使用警报回调,以便其行为几乎类似于window.alert

这些修复后的最终代码:

/**
 * @enum
 * Defines properties for different alert types
 *
**/
const CustomAlertType = {
    info: {color:"#2196F3"},
    success: {color:"#4CAF50"},
    warning: {color:"#ff9800"},
    danger: {color:"#f44336"},
    defaultValues: {color:  "#000000"}
}

window.CustomAlert = function(parameters) {
    var alert = document.createElement("div");
    alert.classList.add("customAlert");
    var title = parameters.title !== undefined ? parameters.title : "ALERT!";
    var message = parameters.message !== undefined ? parameters.message : "Hello World!";
    // Type must be string, of not string use default
    var type = typeof parameters.type == "string" ? parameters.type : "defaultValues";
    // If the type is not valid, it will fall back to default
    const typeObj = CustomAlertType[type] || CustomAlertTyle.defaultValues;


    alert.innerHTML = `
        <span class="close">&times;</span>
        <div class="title" style="background:${typeObj.color};">
            <p>${title}</p>
        </div>
        <div class="message">
            <p>${message}</p>
        </div>
    `;
    // After close is clicked, alert is destroyed and callback is called
    alert.querySelector("span.close").addEventListener("click", function() {
        alert.parentNode.removeChild(alert);
        // If there is a close callback, call it so that code can continue
        if(typeof parameters.onclose == "function") {
            parameters.onclose();
        }
    });
    document.body.appendChild(alert);
};
// Allows to await on alert being closed in `async` functions
function CustomAlertAsync(parameters) {
    return new Promise((resolve, reject)=>{
        parameters.onclose = resolve;
        CustomAlert(parameters);
    });
}
// Example of for loop that waits on alerts to be confirmed
(async ()=>{
    for(let i=0; i<5; ++i) {
        await CustomAlertAsync({title:"for() loop", type: "info", message: "Message #"+(i+1)});
    }
})();

CSS:

body {
  height: 800px;
}

.customAlert {
  margin: auto;
  position: fixed;
  top: 0px;
  left: 0px;
  border: 1px solid black;
  max-height: 350px;
  width: 99.8%;
  color: white;
  background-color: white;
  font-family: sans-serif;
  font-weight: bold;
  overflow: auto;
}
.customAlert .close {
  float: right;
  font-size: 25px;
  cursor: pointer;
  color: black;
  padding: 7px;
  background: red;
  width: 1em;
  height: 1em;
  text-align: center;
}
.customAlert .title {
  padding: 15px;
  height: 2em;
}
.customAlert .message {
  background: #ccc;
  padding: 15px;
}

演示:https://jsfiddle.net/Darker/o5rbLya9/27/

我不太确定你的意思是什么

  

3)标题和消息的高度不起作用

我真的认为您应该在 + 上提出一个单独的问题,该问题将仅使用带有CSS且没有javascript部分的HTML示例。您可以使用开发工具获取警报的HTML。

答案 1 :(得分:0)

尝试一下:

  1. 将JS注释[Write(false)]更改为html注释标签//<!-- -->获取或设置元素中包含的HTML或XML标记。
  2. onclick现在删除警报框,您要删除什么元素? 3
  3. 添加高度以100%提醒

请参见下面的代码

innerHTML