右键单击显示粘滞便笺

时间:2017-06-08 16:19:16

标签: javascript jquery html css contextmenu

我正在尝试编写“粘滞便笺”的创建代码'在具有上下文菜单右键单击选项的网页上。我几乎有它工作,但有一些我似乎无法弄清楚的事情(我已经尝试了几个星期了!)。

我对网络开发很陌生。

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

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

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

请有人指出我正确的方向。我为缺乏基本知识而道歉。

这是我到目前为止所做的:

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代码分成粘滞便笺和上下文菜单部分(这是我最初的原因):

上下文menu.js stickies.js

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

然后,在我右键单击并选择&#34;添加注释&#34;?

后,我将如何运行我的&#39; stickies.js代码?

1 个答案:

答案 0 :(得分:0)

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

在此部分下......

function loadNotes()

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

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

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