简体   繁体   中英

Add dynamic elements with cursor position

I generate dynamic span elements on "Link", "FistName", "LastName" buttons thanks to onclick event. The problem is that I would like to create these spans based on cursor position. I found a script on Internet and changed it to adapt in my function editTag() but no success. Did I miss something in this script or?

Edit: I just founded a similar question, tried to adapt my code, but I still get the problem, impossible to add the span based on cursor position! :/

Inserting a text where cursor is using Javascript/jquery

 var area = document.getElementById("template"); var message = document.getElementById("message"); var maxLength = 160; var re = new RegExp("ô|â|ê|ç"); var myTags = new Object(); var cursorPosition = 0; var smsNode = null; myTags['company'] = '#ENTREPRISE#'; myTags['city'] = '#VILLE#'; myTags['link'] = '#LIEN#'; myTags['firstname'] = '#PRENOM#'; myTags['lastname'] = '#NOM#'; myTags['title'] = '#TITRE#'; $("#smsArea").on('keyup mouseup',function(e) { //console.log(window.getSelection().anchorOffset); /*if(this.hasChildNodes()) { var node = this.childNodes; console.log(node); }*/ /*smsNode = this.textContent; console.log(smsNode);*/ /*if($(window.getSelection().anchorNode).is($(this))) { cursorPosition = 0; } else {*/ cursorPosition = window.getSelection().getRangeAt(0); var smsNode = cursorPosition; console.log(cursorPosition); //} }); function insertAfter(referenceNode, newNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } function editTag(zoneId,tag,button) { var btnSms = document.getElementById(button.id); var zoneDiv = document.getElementById(zoneId + 'Area'); var myButton = document.getElementById(zoneId + tag.ucfirst()); var myLabel = document.createElement('span'); var labels = zoneDiv.getElementsByTagName('span'); var spanSize = labels.length; var delflag = 0; var delIndex = 0; var textNode = document.createTextNode('\ '); //var spanSpace = " "; /*if(btnSms) { btnSms.classList.toggle("btn-danger"); } else { btnSms.classList.toggle("btn-success"); }*/ if(spanSize != 0) { for (myLabId = 0; myLabId < spanSize; myLabId++) { var currentLabel = labels[myLabId]; if(currentLabel.innerHTML === myButton.innerHTML) { delflag = 1; delIndex = myLabId; } } } if(delflag == 1) { btnSms.classList.remove("btn-danger"); btnSms.classList.add("btn-default"); zoneDiv.removeChild(labels[delIndex]); } else { myLabel.setAttribute('class', 'label label-info'); myLabel.setAttribute('data-effect', 'pop'); myLabel.setAttribute('contentEditable', 'false'); myLabel.setAttribute('style','cursor:move;font-size:100%;'); myLabel.setAttribute('name', tag); myLabel.setAttribute('id', 'tag'); myLabel.setAttribute('draggable', 'true'); myLabel.innerHTML = myButton.innerHTML; zoneDiv.appendChild(myLabel); //zoneDiv.appendChild(textNode); //document.getElementById(myLabel).insertAfter(textNode); insertAfter(myLabel, textNode); btnSms.classList.add("btn-danger"); } //Clean breaklines; var bks = zoneDiv.getElementsByTagName('br'); var brSize = bks.length; if(brSize != 0) { zoneDiv.removeChild(bks[0]); } //Event keyboard on deleted elements $("span").dblclick(function(handler) { myLabel.remove(labels[delIndex]); btnSms.classList.remove("btn-danger"); btnSms.classList.add("btn-default"); }); } String.prototype.ucfirst = function() { return this.charAt(0).toUpperCase() + this.substr(1); } 
 #smsArea { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; height: 150px; overflow: auto; padding: 5px; resize: both; width: 100%; } .smstext { /* margin-top: 100px;*/ margin-left: 60px; margin-right: 20px; padding-top: 30px; font-family: verdana, sans-serif; } #mailArea { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; height: 200px; overflow: auto; padding: 5px; resize: both; width: 500px; font-size: 12px; margin-top: 5px; } .mailInput { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; overflow: auto; padding: 5px; resize: both; font-size: 12px; margin-top: 5px; width: 300px; height: 85px; margin-left: 100px; margin-top: -20px; } .mailtext { /* margin-top: 100px;*/ margin-left: 60px; margin-right: 20px; padding-top: 30px; font-family: verdana, sans-serif; } #webtag { margin-top: -392px; margin-left: 555px; width: 569px; } #result { display: none; } #interaction { margin-top: 30px; visibility: hidden; } #cd-popup { background-color: rgba(94, 110, 141, 0.9); opacity: 1; -webkit-transition: opacity 0.3s 0s, visibility 0s 0.3s; -moz-transition: opacity 0.3s 0s, visibility 0s 0.3s; transition: opacity 0.3s 0s, visibility 0s 0.3s; position: relative; width: 100%; max-width: 800px; height: 350px; margin: 4em auto; border-radius: .25em .25em .4em .4em; text-align: center; box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); -webkit-transform: translateY(-40px); -moz-transform: translateY(-40px); -ms-transform: translateY(-40px); -o-transform: translateY(-40px); transform: translateY(-40px); /* Force Hardware Acceleration in WebKit */ -webkit-backface-visibility: hidden; -webkit-transition-property: -webkit-transform; -moz-transition-property: -moz-transform; transition-property: transform; -webkit-transition-duration: 0.3s; -moz-transition-duration: 0.3s; transition-duration: 0.3s; z-index: 1; } #cd-popup.is-visible { opacity: 1; visibility: visible; -webkit-transition: opacity 0.3s 0s, visibility 0s 0s; -moz-transition: opacity 0.3s 0s, visibility 0s 0s; transition: opacity 0.3s 0s, visibility 0s 0s; } #cd-popup p { padding: 3em 1em; margin-left: -250px; height: 100px; } #cd-popup div { float: left; width: 30%; list-style: none; display: block; height: 60px; line-height: 60px; text-transform: uppercase; color: #FFF; -webkit-transition: background-color 0.2s; -moz-transition: background-color 0.2s; transition: background-color 0.2s; } #object { background: #fc7169; border-radius: 0 0 0 .25em; width: 175px; margin-left: -400px; cursor: pointer; padding: 3px 6px; display: inline-block; } #object:hover { background-color: #fc8982; } #body { background: #6495ED; border-radius: 0 0 0 .25em; width: 175px; cursor: pointer; padding: 3px 6px; display: inline-block; margin-left: -150px; } #body:hover { background-color: #fc8982; } #titre { background: #A52A2A; border-radius: 0 0 0 .25em; width: 175px; margin-left: 10px; cursor: pointer; padding: 3px 6px; display: inline-block; } #titre:hover { background-color: #fc8982; } #note { background: #006400; border-radius: 0 0 0 .25em; width: 175px; margin-left: 10px; cursor: pointer; padding: 3px 6px; display: inline-block; } #cd-popup #note:hover { background-color: lightsteelblue; } #cd-popup .cd-popup-close { position: absolute; top: 8px; right: 8px; width: 30px; height: 30px; } #cd-popup .cd-popup-close::before, #cd-popup .cd-popup-close::after { content: ''; position: absolute; top: 12px; width: 14px; height: 3px; background-color: #8f9cb5; } #cd-popup .cd-popup-close::before { -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); left: 8px; } #cd-popup .cd-popup-close::after { -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); right: 8px; } @media only screen and (min-width: 1170px) { #cd-popup { margin: 8em auto; } } .webArea { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; height: 520px; /*overflow: auto;*/ padding: 5px; /*resize: both;*/ width: 630px; font-size: 12px; /*margin-top: 55px;*/ border: 2px dashed #D9D9D9; border-radius: 5px; text-align: center; margin-top: 12%; } .webArea>div { background-color: #FAEBD7; border: 3px dashed #D9D9D9; margin-bottom: 15px; height: 120px; width: 612px; overflow: auto; overflow-x: hidden; /* margin-left: -1.5%;*/ } .webArea>div>div { transition: all .5s; text-align: center; float: left; padding: 1em; margin: 0 1em 1em 0; box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); border-radius: 5px; border: 2px solid black; /*background: #F7F7F7;*/ transition: all .5s ease; width: 582px; /*background-color: #F8F8FF;*/ height: 110px; } .dropTarget>div>div>span { font-style: italic; margin-right: 5%; font-size: 16px; } .webArea>div>div>input { margin-right: 25%; width: 250px; height: 40px; background-color: white; } .webArea>div>div:active { /*-webkit-animation: wiggle 0.3s 0s infinite ease-in; animation: wiggle 0.3s 0s infinite ease-in;*/ opacity: .6; border: 2px solid #000; } #mailArea { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; height: 200px; overflow: auto; padding: 5px; resize: both; width: 500px; font-size: 12px; margin-top: 5px; } #containerZone { border: 1px solid; border-radius: 25px; */ margin: 3%; width: 70%; height: 40px; text-align: center; font-weight: bold; color: #000000; margin: auto; margin-top: 8%; margin-left: -450px; } #containerZone2 { border: 1px solid; border-radius: 25px; width: 70%; height: 40px; text-align: center; font-weight: bold; color: #000000; margin: auto; margin-top: 100%; margin-left: -450px; } #webtags { margin-top: -40px; } #webtags>div { margin-left: 20px; } #modalTagBody { height: 120px; } #btnTag { margin-top: 20px; margin-right: 15px; } 
 <html> <head> <meta charset="utf-8"> <title>Drag & drop Tag</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- Optional theme --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <!-- Latest compiled and minified JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.0/jquery-confirm.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.0/jquery-confirm.min.js"></script> </head> <body> <div class="container mtb"> <div class="row"> <TMPL_IF NAME="PROFILE"> <form role="form" action="<TMPL_VAR NAME=MYURL>?rm=saveTemplate" method="POST" enctype="application/x-www-form-urlencoded"> <TMPL_LOOP NAME="DATA"> <input type="hidden" id='id' name="id" value="<TMPL_VAR NAME=ID>" /> <TMPL_IF NAME="TEMPLATE"> <div class="panel panel-primary" id="panels" data-effect="helix"> <div class="panel-heading">SMS Message</div> <div class="panel-body"> <div class="col-lg-6"> <div class="form-group"> </div> <input type="hidden" name="rm" value="saveTemplate" /> <div id="smsArea" class="form-control" contenteditable="true"> <p id="smsDraft"> <TMPL_VAR NAME=TEMPLATE> </p> </div><br /> <div>position: <span id="position"></span></div> <a href="#" class="btn btn-primary" onClick="saveMessage('sms');">Save</a> <a href="#" class="btn btn-primary" onClick="previewMessage('sms');" data-toggle="modal" data-target="#myModal2">Preview</a> <a href="#" class="btn btn-primary" onClick="testMessage('sms');" data-toggle="modal" data-target="#myModal">SMS Costs</a> <br> </div> <div class="col-lg-6" id='smsTags'> <h4 for="template">Personnalization</h4> <span class="btn btn-default" onClick="editTag('sms','link', this)" id="smsLink" title="link of your website" draggable="true">Link</span> <span class="btn btn-default" onClick="editTag('sms','firstname',this)" id="smsFirstname" title="your firstname" draggable="true">Firstname</span> <span class="btn btn-default" onClick="editTag('sms','lastname',this)" id="smsLastname" title="your lastname" draggable="true">Lastname</span> </div> <div class="col-lg-6" style="margin-top: 30px"> </div> </div> </TMPL_LOOP> </div> <! --/row --> </div> <! --/container --> </div> </body> </html> 

Finally, I have found a solution to my problem !

I have to replace the method window.getSelection().anchorOffset by window.getSelection().getRangeAt(0) to get the cursor position when entering text in the area and to get also the node on which I was working on, to save these results into cursorPosition variable. And after, I had to use again this variable in editTag() function to insert the span tag according to the cursor position, by doing : cursorPosition.insertNode(myLabel);

 var area = document.getElementById("template"); var message = document.getElementById("message"); var maxLength = 160; var re = new RegExp("ô|â|ê|ç"); var myTags = new Object(); var cursorPosition = 0; var smsNode = null; myTags['company'] = '#ENTREPRISE#'; myTags['city'] = '#VILLE#'; myTags['link'] = '#LIEN#'; myTags['firstname'] = '#PRENOM#'; myTags['lastname'] = '#NOM#'; myTags['title'] = '#TITRE#'; $("#smsArea").on('keyup mouseup',function(e) { //console.log(window.getSelection().anchorOffset); /*if(this.hasChildNodes()) { var node = this.childNodes; console.log(node); }*/ /*smsNode = this.textContent; console.log(smsNode);*/ /*if($(window.getSelection().anchorNode).is($(this))) { cursorPosition = 0; } else {*/ cursorPosition = window.getSelection().getRangeAt(0); //console.log(cursorPosition); //} }); function insertAfter(referenceNode, newNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } function editTag(zoneId,tag,button) { var btnSms = document.getElementById(button.id); var zoneDiv = document.getElementById(zoneId + 'Area'); var myButton = document.getElementById(zoneId + tag.ucfirst()); var myLabel = document.createElement('span'); var labels = zoneDiv.getElementsByTagName('span'); var spanSize = labels.length; var delflag = 0; var delIndex = 0; var textNode = document.createTextNode('\ '); /*if(btnSms) { btnSms.classList.toggle("btn-danger"); } else { btnSms.classList.toggle("btn-success"); }*/ if(spanSize != 0) { for (myLabId = 0; myLabId < spanSize; myLabId++) { var currentLabel = labels[myLabId]; if(currentLabel.innerHTML === myButton.innerHTML) { delflag = 1; delIndex = myLabId; } } } if(delflag == 1) { btnSms.classList.remove("btn-danger"); btnSms.classList.add("btn-default"); zoneDiv.removeChild(labels[delIndex]); } else { myLabel.setAttribute('class', 'label label-info'); myLabel.setAttribute('data-effect', 'pop'); myLabel.setAttribute('contentEditable', 'false'); myLabel.setAttribute('style','cursor:move;font-size:100%;'); myLabel.setAttribute('name', tag); myLabel.setAttribute('id', 'tag'); myLabel.setAttribute('draggable', 'true'); myLabel.innerHTML = myButton.innerHTML; //zoneDiv.appendChild(myLabel); cursorPosition.insertNode(myLabel); console.log(cursorPosition); //zoneDiv.appendChild(textNode); //document.getElementById(myLabel).insertAfter(textNode); insertAfter(myLabel, textNode); btnSms.classList.add("btn-danger"); } //Clean breaklines; var bks = zoneDiv.getElementsByTagName('br'); var brSize = bks.length; if(brSize != 0) { zoneDiv.removeChild(bks[0]); } //Event keyboard on deleted elements $("span").dblclick(function(handler) { myLabel.remove(labels[delIndex]); btnSms.classList.remove("btn-danger"); btnSms.classList.add("btn-default"); }); } String.prototype.ucfirst = function() { return this.charAt(0).toUpperCase() + this.substr(1); } 
 #smsArea { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; height: 150px; overflow: auto; padding: 5px; resize: both; width: 100%; } .smstext { /* margin-top: 100px;*/ margin-left: 60px; margin-right: 20px; padding-top: 30px; font-family: verdana, sans-serif; } #mailArea { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; height: 200px; overflow: auto; padding: 5px; resize: both; width: 500px; font-size: 12px; margin-top: 5px; } .mailInput { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; overflow: auto; padding: 5px; resize: both; font-size: 12px; margin-top: 5px; width: 300px; height: 85px; margin-left: 100px; margin-top: -20px; } .mailtext { /* margin-top: 100px;*/ margin-left: 60px; margin-right: 20px; padding-top: 30px; font-family: verdana, sans-serif; } #webtag { margin-top: -392px; margin-left: 555px; width: 569px; } #result { display: none; } #interaction { margin-top: 30px; visibility: hidden; } #cd-popup { background-color: rgba(94, 110, 141, 0.9); opacity: 1; -webkit-transition: opacity 0.3s 0s, visibility 0s 0.3s; -moz-transition: opacity 0.3s 0s, visibility 0s 0.3s; transition: opacity 0.3s 0s, visibility 0s 0.3s; position: relative; width: 100%; max-width: 800px; height: 350px; margin: 4em auto; border-radius: .25em .25em .4em .4em; text-align: center; box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); -webkit-transform: translateY(-40px); -moz-transform: translateY(-40px); -ms-transform: translateY(-40px); -o-transform: translateY(-40px); transform: translateY(-40px); /* Force Hardware Acceleration in WebKit */ -webkit-backface-visibility: hidden; -webkit-transition-property: -webkit-transform; -moz-transition-property: -moz-transform; transition-property: transform; -webkit-transition-duration: 0.3s; -moz-transition-duration: 0.3s; transition-duration: 0.3s; z-index: 1; } #cd-popup.is-visible { opacity: 1; visibility: visible; -webkit-transition: opacity 0.3s 0s, visibility 0s 0s; -moz-transition: opacity 0.3s 0s, visibility 0s 0s; transition: opacity 0.3s 0s, visibility 0s 0s; } #cd-popup p { padding: 3em 1em; margin-left: -250px; height: 100px; } #cd-popup div { float: left; width: 30%; list-style: none; display: block; height: 60px; line-height: 60px; text-transform: uppercase; color: #FFF; -webkit-transition: background-color 0.2s; -moz-transition: background-color 0.2s; transition: background-color 0.2s; } #object { background: #fc7169; border-radius: 0 0 0 .25em; width: 175px; margin-left: -400px; cursor: pointer; padding: 3px 6px; display: inline-block; } #object:hover { background-color: #fc8982; } #body { background: #6495ED; border-radius: 0 0 0 .25em; width: 175px; cursor: pointer; padding: 3px 6px; display: inline-block; margin-left: -150px; } #body:hover { background-color: #fc8982; } #titre { background: #A52A2A; border-radius: 0 0 0 .25em; width: 175px; margin-left: 10px; cursor: pointer; padding: 3px 6px; display: inline-block; } #titre:hover { background-color: #fc8982; } #note { background: #006400; border-radius: 0 0 0 .25em; width: 175px; margin-left: 10px; cursor: pointer; padding: 3px 6px; display: inline-block; } #cd-popup #note:hover { background-color: lightsteelblue; } #cd-popup .cd-popup-close { position: absolute; top: 8px; right: 8px; width: 30px; height: 30px; } #cd-popup .cd-popup-close::before, #cd-popup .cd-popup-close::after { content: ''; position: absolute; top: 12px; width: 14px; height: 3px; background-color: #8f9cb5; } #cd-popup .cd-popup-close::before { -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); left: 8px; } #cd-popup .cd-popup-close::after { -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); right: 8px; } @media only screen and (min-width: 1170px) { #cd-popup { margin: 8em auto; } } .webArea { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; height: 520px; /*overflow: auto;*/ padding: 5px; /*resize: both;*/ width: 630px; font-size: 12px; /*margin-top: 55px;*/ border: 2px dashed #D9D9D9; border-radius: 5px; text-align: center; margin-top: 12%; } .webArea>div { background-color: #FAEBD7; border: 3px dashed #D9D9D9; margin-bottom: 15px; height: 120px; width: 612px; overflow: auto; overflow-x: hidden; /* margin-left: -1.5%;*/ } .webArea>div>div { transition: all .5s; text-align: center; float: left; padding: 1em; margin: 0 1em 1em 0; box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); border-radius: 5px; border: 2px solid black; /*background: #F7F7F7;*/ transition: all .5s ease; width: 582px; /*background-color: #F8F8FF;*/ height: 110px; } .dropTarget>div>div>span { font-style: italic; margin-right: 5%; font-size: 16px; } .webArea>div>div>input { margin-right: 25%; width: 250px; height: 40px; background-color: white; } .webArea>div>div:active { /*-webkit-animation: wiggle 0.3s 0s infinite ease-in; animation: wiggle 0.3s 0s infinite ease-in;*/ opacity: .6; border: 2px solid #000; } #mailArea { -moz-appearance: textfield-multiline; -webkit-appearance: textarea; height: 200px; overflow: auto; padding: 5px; resize: both; width: 500px; font-size: 12px; margin-top: 5px; } #containerZone { border: 1px solid; border-radius: 25px; */ margin: 3%; width: 70%; height: 40px; text-align: center; font-weight: bold; color: #000000; margin: auto; margin-top: 8%; margin-left: -450px; } #containerZone2 { border: 1px solid; border-radius: 25px; width: 70%; height: 40px; text-align: center; font-weight: bold; color: #000000; margin: auto; margin-top: 100%; margin-left: -450px; } #webtags { margin-top: -40px; } #webtags>div { margin-left: 20px; } #modalTagBody { height: 120px; } #btnTag { margin-top: 20px; margin-right: 15px; } 
 <html> <head> <meta charset="utf-8"> <title>Drag & drop Tag</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- Optional theme --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <!-- Latest compiled and minified JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.0/jquery-confirm.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.0/jquery-confirm.min.js"></script> </head> <body> <div class="container mtb"> <div class="row"> <TMPL_IF NAME="PROFILE"> <form role="form" action="<TMPL_VAR NAME=MYURL>?rm=saveTemplate" method="POST" enctype="application/x-www-form-urlencoded"> <TMPL_LOOP NAME="DATA"> <input type="hidden" id='id' name="id" value="<TMPL_VAR NAME=ID>" /> <TMPL_IF NAME="TEMPLATE"> <div class="panel panel-primary" id="panels" data-effect="helix"> <div class="panel-heading">SMS Message</div> <div class="panel-body"> <div class="col-lg-6"> <div class="form-group"> </div> <input type="hidden" name="rm" value="saveTemplate" /> <div id="smsArea" class="form-control" contenteditable="true"> <p id="smsDraft"> <TMPL_VAR NAME=TEMPLATE> </p> </div><br /> <div>position: <span id="position"></span></div> <a href="#" class="btn btn-primary" onClick="saveMessage('sms');">Save</a> <a href="#" class="btn btn-primary" onClick="previewMessage('sms');" data-toggle="modal" data-target="#myModal2">Preview</a> <a href="#" class="btn btn-primary" onClick="testMessage('sms');" data-toggle="modal" data-target="#myModal">SMS Costs</a> <br> </div> <div class="col-lg-6" id='smsTags'> <h4 for="template">Personnalization</h4> <span class="btn btn-default" onClick="editTag('sms','link', this)" id="smsLink" title="link of your website" draggable="true">Link</span> <span class="btn btn-default" onClick="editTag('sms','firstname',this)" id="smsFirstname" title="your firstname" draggable="true">Firstname</span> <span class="btn btn-default" onClick="editTag('sms','lastname',this)" id="smsLastname" title="your lastname" draggable="true">Lastname</span> </div> <div class="col-lg-6" style="margin-top: 30px"> </div> </div> </TMPL_LOOP> </div> <! --/row --> </div> <! --/container --> </div> </body> </html> 

Get cursor position with pageX , pageY . Here is the demo:

 stage = document.querySelector('.stage') stage.addEventListener('click', e => { let spanEl = document.createElement('span') spanEl.style.top = e.pageY + 'px' spanEl.style.left = e.pageX + 'px' spanEl.style.background = '#'+(Math.random()*0xFFFFFF<<0).toString(16) stage.appendChild(spanEl) e.preventDefault() }) 
 body { margin: 0; } div.stage { background: yellow; width: 100%; min-height: 300px; padding: 0; overflow: hidden; position: relative; } span { position: absolute; width: 30px; height: 20px; background-color:teal; } 
 <div class="stage"> click to add </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM