添加光标位置

时间:2018-03-06 06:01:23

标签: javascript jquery html css

由于onclick事件,我在“Link”,“FistName”,“LastName”按钮上生成动态span元素。问题是我想根据光标位置创建这些跨度。我在Internet上找到了一个脚本并将其更改为在我的函数editTag()中进行了调整但没有成功。我错过了这个剧本中的内容吗?

编辑: 我刚刚创建了一个类似的问题,尝试调整我的代码,但我仍然遇到问题,无法根据光标位置添加跨度! :/

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('\u00A0');

	//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>

2 个答案:

答案 0 :(得分:0)

最后,我找到了解决问题的方法!

我必须通过window.getSelection()。getRangeAt(0)替换方法window.getSelection()。anchorOffset,以便在区域中输入文本时获取光标位置,并获取我正在处理的节点,将这些结果保存到cursorPosition变量中。 之后,我不得不再次使用editTag()函数中的这个变量来根据光标位置插入span标记,方法是:cursorPosition.insertNode(myLabel);

&#13;
&#13;
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('\u00A0');

	/*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);
}
&#13;
#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;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

使用pageXpageY获取光标位置。 这是演示:

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>