Reputation: 5355
I would like to append/prepend a space on the outer tags.
I tried the following:
var $elem = $('<span>', {
'data-function': "addSynonym",
'data-options': '[ test1, test2, test3]',
'html': $('<span>', {
'text': 'test4',
'css': {
backgroundColor: 'yellow'
}
})
});
$elem.append(" ")
$elem.prepend(" ");
console.log($elem[0]);
console.log($elem[0].innerHTML);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
As you can see only the inner tag has the spaces.
However, I would like to have it on the outer tag. Like the following:
<span data-function="addSynonym" data-options="[ test1, test2, test3]"><span style="background-color: yellow;">test4</span></span>
Any suggestions how to do this?
I appreciate your replies!
Upvotes: 4
Views: 619
Reputation: 2773
There are many ways to append space on outside of element. but unless you wrap it inside another span it will not work.
var $elem = $('<span>', {
'data-function': "addSynonym",
'data-options': '[ test1, test2, test3]',
'html': $('<span>', {
'text': 'test4',
'css': {
backgroundColor: 'yellow'
}
})
});
$elem.append(" ")
$elem.prepend(" ");
const textNode = ' '
$elem.before(textNode)
$elem.after(textNode)
console.log($elem[0]);
console.log($elem[0].innerHTML);
var $elemupdated = $('<span>', {
'html': $elem[0].innerHTML
});
console.log($elemupdated[0].outerHTML);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 0
Reputation: 762
Maybe this can help you.
If you can add pseudo ::after
::before
to your style.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.mySpan::before{
content: ' ';
}
.mySpan::after{
content: ' ';
}
</style>
</head>
<body>
<div id="target">my text</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var $elem = $('<span>', {
'class': 'mySpan',
'data-function': "addSynonym",
'data-options': '[ test1, test2, test3]',
'html': $('<span>', {
'text': 'test4',
'css': {
backgroundColor: 'yellow'
}
})
})
$("#target").append($elem)
</script>
</body>
</html>
If you want pure Javascript solution I think you must add space to your element container.
Kind Regards
Amin
Upvotes: 0
Reputation: 446
Given that nodes are not aware of what's going on around them, this is a perfect scenario for DocumentFragments.
let $fragment = $(document.createDocumentFragment());
let $elem = $('<span>', {
'data-function': "addSynonym",
'data-options': '[ test1, test2, test3]',
'html': $('<span>', {
'text': 'test4',
'css': {
backgroundColor: 'yellow'
}
})
});
$fragment.append('\u00A0', $elem, '\u00A0');
$container.append($fragment);
// $container => ' <span...><span...>test4</span></span> '
$elem.append('!');
// $container => ' <span...><span...>test4</span>!</span> '
Upvotes: 2
Reputation: 37318
You can use another span
element to wrap your text. That won't affect anything in your text neither in the way you may want to use $elem
afterwards. Then create a text node using NO-BREAK SPACE' (U+00A0)
which is equivalent to
and use it to compile your final text node.
var colors = ['yellow', 'red', 'lightgreen', 'cyan'];
var currentColor = 0;
// Create a text node using Unicode Character 'NO-BREAK SPACE' (U+00A0)
var $spaceNode = $(document.createTextNode('\u00A0'));
// Wrap the text node to a span with a begin and end sibling of the space text node clone
var $elem = $('<span>').append(
$spaceNode.clone(),
$('<span>', {
'data-function': "addSynonym",
'data-options': '[test1, test2, test3]',
'html': $('<span>', {
'text': 'test4',
'css': {
backgroundColor: 'yellow'
}
})
}),
$spaceNode.clone()
);
function appendText() {
// Output $elem node outer HTML to a preview element
$('#elem_html').text($elem[0].outerHTML);
// Clone the $elem so we can use it multiple times
var $elemClone = $elem.clone();
// Append the cloned $elem to the DOM
$('#editor').append($elemClone);
// Apply manipulation demo timer
hookElemChange($elemClone);
}
// Handle add text button click
$('#add_text').on('click', function() {
appendText();
});
// Handle change $elem color button click
$('#change_text_color').on('click', function() {
var newColor;
// Generate a random color
do {
newColor = Math.floor(Math.random() * Math.floor(colors.length));
} while(newColor === currentColor);
currentColor = newColor;
// Change the $elem inner span background color to a random color
$elem.find('span > span').css('background-color', colors[currentColor]);
// We can also use specific element selector using data-function with "addSynonym" value
// $elem.find('span[data-function="addSynonym"] > span').css('background-color', colors[currentColor]);
// Append the text to the DOM
appendText();
});
// A timer for each element that parses and increases the text prepending number
// This is for to demontrate that each node can be manipulated with no restrictions after creating/cloning
function hookElemChange($element) {
setInterval(function() {
var $currentElem = $element.find('span[data-function="addSynonym"] > span');
var text = $currentElem.text();
var textParts = text.match(/([a-z]+)(\d+)/);
if (textParts) {
var num = parseInt(textParts[2]);
var newText = textParts[1] + ++num;
$currentElem.text(newText);
}
}, 1000);
}
#editor {
border: 1px solid grey;
height: 100px;
margin-bottom: 10px;
overflow-wrap: break-word;
overflow: auto;
}
#elem_html {
white-space: normal;
margin-top: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="editor"></div>
<div>
<button id="add_text">Add text</button>
<button id="change_text_color">Change color</button>
</div>
<div>
<pre id="elem_html"></pre>
</div>
As you can see, you can save and access each cloned $elem
afterwards with both span
selector ($elem.find('span')
) or even more specific using data-function
name span[data-function="addSynonym"]
($elem.find('span[data-function="addSynonym"]')
) and for the inner element span > span
or span[data-function="addSynonym"] > span
.
Another way is to directly append everything to the target node if you want to keep that specific $elem
structure:
var colors = ['yellow', 'red', 'lightgreen', 'cyan'];
var currentColor = 0;
// Create a text node using Unicode Character 'NO-BREAK SPACE' (U+00A0)
var $spaceNode = $(document.createTextNode('\u00A0'));
// Create the node with initial structure
var $elem = $('<span>', {
'data-function': "addSynonym",
'data-options': '[test1, test2, test3]',
'html': $('<span>', {
'text': 'test4',
'css': {
backgroundColor: 'yellow'
}
})
});
function appendText() {
// Clone the $elem so we can use it multiple times
var $elemClone = $elem.clone();
// Append the cloned $elem to the DOM
$('#editor').append($spaceNode.clone(), $elemClone, $spaceNode.clone());
// Output #editor node inner HTML to a preview element
$('#elem_html').text($('#editor')[0].innerHTML);
// Apply manipulation demo timer
hookElemChange($elemClone);
}
// Handle add text button click
$('#add_text').on('click', function() {
appendText();
});
// Handle change $elem color button click
$('#change_text_color').on('click', function() {
var newColor;
// Generate a random color
do {
newColor = Math.floor(Math.random() * Math.floor(colors.length));
} while(newColor === currentColor);
currentColor = newColor;
// Change the $elem inner span background color to a random color
$elem.find('span').css('background-color', colors[currentColor]);
// We can also use specific element selector using data-function with "addSynonym" value
// $elem.find('span[data-function="addSynonym"] > span').css('background-color', colors[currentColor]);
// Append the text to the DOM
appendText();
});
// A timer for each element that parses and increases the text prepending number
// This is for to demontrate that each node can be manipulated with no restrictions after creating/cloning
function hookElemChange($element) {
setInterval(function() {
var $currentElem = $element.find('span');
var text = $currentElem.text();
var textParts = text.match(/([a-z]+)(\d+)/);
if (textParts) {
var num = parseInt(textParts[2]);
var newText = textParts[1] + ++num;
$currentElem.text(newText);
}
}, 1000);
}
#editor {
border: 1px solid grey;
height: 100px;
margin-bottom: 10px;
overflow-wrap: break-word;
overflow: auto;
}
#elem_html {
white-space: normal;
margin-top: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="editor"></div>
<div>
<button id="add_text">Add text</button>
<button id="change_text_color">Change color</button>
</div>
<div><pre id="elem_html"></pre></div>
Using this way, you'll have to access inner span using just span
($elem.find('span')
) selector.
Upvotes: 6
Reputation: 4595
I would just reference the vanilla outerHTML
manually.
var $elem = $('<span>', {
'data-function': "addSynonym",
'data-options': '[ test1, test2, test3]',
'html': $('<span>', {
'text': 'test4',
'css': {
backgroundColor: 'yellow'
}
})
});
$elem.append(" ");
$elem.prepend(" ");
console.log(" " + $elem[0].outerHTML + " ");
console.log($elem[0].innerHTML);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 0
Reputation: 545
In jQuery, insertBefore
/before
and insertAfter
/after
are the methods used to insert elements before or after the target element.
is not element, though, so you have to create a text node:
const textNode = ' '
$('.some-element').before(textNode)
$('.some-element').after(textNode)
See example:
https://jsfiddle.net/yq1jfd5z/1/
Upvotes: -1