javascript - 右键单击时显示便签

标签 javascript jquery html css contextmenu

我正在尝试使用上下文菜单右键单击选项对网页上“便签”的创建进行编码。我几乎让它工作了,但有几件事我似乎无法弄清楚(我已经尝试了几个星期了!)。

我对网络开发还很陌生。

我已经为便签和上下文右键单击菜单组合了一些代码。我遇到的问题是,当页面第一次加载时,会出现一个便签:我不希望这种情况发生。我希望它最初加载时没有可见的便签,并且只有在添加它们后才可见,或者如果它们以前添加并自动保存(这已经是代码的一部分)。

所以我使用 display: none 来隐藏 css “note” 元素。但是,如果我这样做,那么当我右键单击添加注释时,它根本不会显示。所以我知道我需要告诉它显示它是否是由我的右键单击菜单选项创建的,但我一直在努力了解如何执行此操作。

我遇到的第二个问题是便签是在随机位置创建的;然而,我希望它们显示在我右键单击的位置旁边。

请有人指出我正确的方向。对于我缺乏基础知识,我深表歉意。

这是我目前所拥有的:

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Custom Right Click Menu</title>
    <link rel="stylesheet" type="text/css" href="stickies.css" />

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script type="text/javascript" src="stickies.js"></script>

</head>
<body>

<!-- Menu div initially hidden -->
<script>
document.getElementById("newNoteButton").disabled = !db;
</script>
<div class="menu" id="newNoteButton" onclick="newNote()">
    <ul>
        <a href="#"><li>Add Note</li></a>
    </ul>
</div>
</body>
</html>

CSS

.menu{
    width: 100px;
    background: #000;
    color: #fff;
    position:absolute;
    z-index: 999999;
    display: none;
    box-shadow: 0 0 10px #713C3C;
}
.menu ul{
    list-style: none;
    padding: 0;
    margin:0;
}
.menu ul a{
    text-decoration: none;
}
.menu ul li{
    width: 88%;
    padding: 6%;
    background-color: #F04D44;
    color: #fff;
}
.menu ul li:hover{
    background-color: #F7BA4B;
    color: #444343;
}

body {
    font-family: 'Lucida Grande', 'Helvetica', sans-serif;
}

.note {
    background-color: rgb(255, 240, 70);
    height: 100px;
    padding: 10px;
    position: absolute;
    width: 200px;
    -webkit-box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.5);
}

.note:hover .closebutton {
    display: block;
}

.closebutton {
    display: none;
    background-image: url(deleteButton.png);
    height: 30px;
    position: absolute;
    left: -15px;
    top: -15px;
    width: 30px;
}

.closebutton:active {
    background-image: url(deleteButtonPressed.png);
}

.edit {
    outline: none;
}

.timestamp {
    position: absolute;
    left: 0px;
    right: 0px;
    bottom: 0px;
    font-size: 9px;
    background-color: #db0;
    color: white;
    border-top: 1px solid #a80;
    padding: 2px 4px;
    text-align: right;
}

Javascript

$(document).ready(function () {
        $("html").on("contextmenu",function(e){
               //prevent default context menu for right click
               e.preventDefault();

               var menu = $(".menu"); 

               //hide menu if already shown
               menu.hide(); 

               //get x and y values of the click event
               var pageX = e.pageX;
               var pageY = e.pageY;

               //position menu div near mouse cliked area
               menu.css({top: pageY , left: pageX});

               var mwidth = menu.width();
               var mheight = menu.height();
               var screenWidth = $(window).width();
               var screenHeight = $(window).height();

               //if window is scrolled
               var scrTop = $(window).scrollTop();

               //if the menu is close to right edge of the window
               if(pageX+mwidth > screenWidth){
                menu.css({left:pageX-mwidth});
               }

               //if the menu is close to bottom edge of the window
               if(pageY+mheight > screenHeight+scrTop){
                menu.css({top:pageY-mheight});
               }

               //finally show the menu
               menu.show();
        }); 

        $("html").on("click", function(){
            $(".menu").hide();
        });
    });


var db = null;

try {
    if (window.openDatabase) {
        db = openDatabase("NoteTest", "1.0", "HTML5 Database API example", 200000);
        if (!db)
            alert("Failed to open the database on disk.  This is probably because the version was bad or there is not enough space left in this domain's quota");
    } else
        alert("Couldn't open the database.  Please try with a WebKit nightly with this feature enabled");
} catch(err) {
    db = null;
    alert("Couldn't open the database.  Please try with a WebKit nightly with this feature enabled");
}

var captured = null;
var highestZ = 0;
var highestId = 0;

function Note()
{
    var self = this;

    var note = document.createElement('div');
    note.className = 'note';
    note.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
    note.addEventListener('click', function() { return self.onNoteClick() }, false);
    this.note = note;

    var close = document.createElement('div');
    close.className = 'closebutton';
    close.addEventListener('click', function(event) { return self.close(event) }, false);
    note.appendChild(close);

    var edit = document.createElement('div');
    edit.className = 'edit';
    edit.setAttribute('contenteditable', true);
    edit.addEventListener('keyup', function() { return self.onKeyUp() }, false);
    note.appendChild(edit);
    this.editField = edit;

    var ts = document.createElement('div');
    ts.className = 'timestamp';
    ts.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
    note.appendChild(ts);
    this.lastModified = ts;

    document.body.appendChild(note);
    return this;
}

Note.prototype = {
    get id()
    {
        if (!("_id" in this))
            this._id = 0;
        return this._id;
    },

    set id(x)
    {
        this._id = x;
    },

    get text()
    {
        return this.editField.innerHTML;
    },

    set text(x)
    {
        this.editField.innerHTML = x;
    },

    get timestamp()
    {
        if (!("_timestamp" in this))
            this._timestamp = 0;
        return this._timestamp;
    },

    set timestamp(x)
    {
        if (this._timestamp == x)
            return;

        this._timestamp = x;
        var date = new Date();
        date.setTime(parseFloat(x));
        this.lastModified.textContent = modifiedString(date);
    },

    get left()
    {
        return this.note.style.left;
    },

    set left(x)
    {
        this.note.style.left = x;
    },

    get top()
    {
        return this.note.style.top;
    },

    set top(x)
    {
        this.note.style.top = x;
    },

    get zIndex()
    {
        return this.note.style.zIndex;
    },

    set zIndex(x)
    {
        this.note.style.zIndex = x;
    },

    close: function(event)
    {
        this.cancelPendingSave();

        var note = this;
        db.transaction(function(tx)
        {
            tx.executeSql("DELETE FROM WebKitStickyNotes WHERE id = ?", [note.id]);
        });

        var duration = event.shiftKey ? 2 : .25;
        this.note.style.webkitTransition = '-webkit-transform ' + duration + 's ease-in, opacity ' + duration + 's ease-in';
        this.note.offsetTop; // Force style recalc
        this.note.style.webkitTransformOrigin = "0 0";
        this.note.style.webkitTransform = 'skew(30deg, 0deg) scale(0)';
        this.note.style.opacity = '0';

        var self = this;
        setTimeout(function() { document.body.removeChild(self.note) }, duration * 1000);
    },

    saveSoon: function()
    {
        this.cancelPendingSave();
        var self = this;
        this._saveTimer = setTimeout(function() { self.save() }, 200);
    },

    cancelPendingSave: function()
    {
        if (!("_saveTimer" in this))
            return;
        clearTimeout(this._saveTimer);
        delete this._saveTimer;
    },

    save: function()
    {
        this.cancelPendingSave();

        if ("dirty" in this) {
            this.timestamp = new Date().getTime();
            delete this.dirty;
        }

        var note = this;
        db.transaction(function (tx)
        {
            tx.executeSql("UPDATE WebKitStickyNotes SET note = ?, timestamp = ?, left = ?, top = ?, zindex = ? WHERE id = ?", [note.text, note.timestamp, note.left, note.top, note.zIndex, note.id]);
        });
    },

    saveAsNew: function()
    {
        this.timestamp = new Date().getTime();

        var note = this;
        db.transaction(function (tx) 
        {
            tx.executeSql("INSERT INTO WebKitStickyNotes (id, note, timestamp, left, top, zindex) VALUES (?, ?, ?, ?, ?, ?)", [note.id, note.text, note.timestamp, note.left, note.top, note.zIndex]);
        }); 
    },

    onMouseDown: function(e)
    {
        captured = this;
        this.startX = e.clientX - this.note.offsetLeft;
        this.startY = e.clientY - this.note.offsetTop;
        this.zIndex = ++highestZ;

        var self = this;
        if (!("mouseMoveHandler" in this)) {
            this.mouseMoveHandler = function(e) { return self.onMouseMove(e) }
            this.mouseUpHandler = function(e) { return self.onMouseUp(e) }
        }

        document.addEventListener('mousemove', this.mouseMoveHandler, true);
        document.addEventListener('mouseup', this.mouseUpHandler, true);

        return false;
    },

    onMouseMove: function(e)
    {
        if (this != captured)
            return true;

        this.left = e.clientX - this.startX + 'px';
        this.top = e.clientY - this.startY + 'px';
        return false;
    },

    onMouseUp: function(e)
    {
        document.removeEventListener('mousemove', this.mouseMoveHandler, true);
        document.removeEventListener('mouseup', this.mouseUpHandler, true);

        this.save();
        return false;
    },

    onNoteClick: function(e)
    {
        this.editField.focus();
        getSelection().collapseToEnd();
    },

    onKeyUp: function()
    {
        this.dirty = true;
        this.saveSoon();
    },
}

function loaded()
{
    db.transaction(function(tx) {
        tx.executeSql("SELECT COUNT(*) FROM WebkitStickyNotes", [], function(result) {
            loadNotes();
        }, function(tx, error) {
            tx.executeSql("CREATE TABLE WebKitStickyNotes (id REAL UNIQUE, note TEXT, timestamp REAL, left TEXT, top TEXT, zindex REAL)", [], function(result) { 
                loadNotes(); 
            });
        });
    });
}

function loadNotes()
{
    db.transaction(function(tx) {
        tx.executeSql("SELECT id, note, timestamp, left, top, zindex FROM WebKitStickyNotes", [], function(tx, result) {
            for (var i = 0; i < result.rows.length; ++i) {
                var row = result.rows.item(i);
                var note = new Note();
                note.id = row['id'];
                note.text = row['note'];
                note.timestamp = row['timestamp'];
                note.left = row['left'];
                note.top = row['top'];
                note.zIndex = row['zindex'];

                if (row['id'] > highestId)
                    highestId = row['id'];
                if (row['zindex'] > highestZ)
                    highestZ = row['zindex'];
            }

            if (!result.rows.length)
                newNote();
        }, function(tx, error) {
            alert('Failed to retrieve notes from database - ' + error.message);
            return;
        });
    });
}

function modifiedString(date)
{
    return 'Last Modified: ' + date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
}

function newNote()
{
    var note = new Note();
    note.id = ++highestId;
    note.timestamp = new Date().getTime();
    note.left = Math.round(Math.random() * 400) + 'px';
    note.top = Math.round(Math.random() * 500) + 'px';
    note.zIndex = ++highestZ;
    note.saveAsNew();
}

if (db != null)
    addEventListener('load', loaded, false);

编辑:

所以我想解决这个问题的方法是只在选择/触发右键单击上下文菜单后加载 javascript 的便签部分。

我可以将我的 js 代码分为便签和上下文菜单部分(这是我最初的部分):

上下文菜单.js 贴纸.js

然后从 html 文件的初始加载中删除 stickies.js。

然后,当我右键单击并选择“添加注释”后,我将如何运行我的“stickies.js”代码?

最佳答案

另一个论坛上有人为我解决了这个问题。

在这个部分...

function loadNotes()

我删除了以下代码,如果数据库为空,它不再加载初始便签元素:

if (!result.rows.length)
                newNote();

现在我只需要弄清楚如何将新笔记的创建放置在光标附近(我右键单击的位置)而不是随机放置。

关于javascript - 右键单击时显示便签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44440909/

相关文章:

jquery - 如何在ajax成功时重新加载DFP广告管理系统广告?

jquery - 将 jQuery 的 ajax() 函数与 SSL 客户端证书结合使用

jquery - div 的条纹类

html - 水平导航栏中的文本(使用 ul 和 li)未垂直居中

php - 根据列表验证邮政编码

JavaScript - 等待/阻塞,直到构造函数完全加载

javascript - 使用 grunt 构建时,如何/将什么部署到我的 tomcat 服务器?

javascript - 如何限制文本框中的逗号少于 3 个?

javascript - Knockout.js 中计算的可观察函数的数据上下文

javascript - 如何在 HTML 的特定部分添加和删除 'table'?