问题
I've added some codes to add a dropdown menu to TinyMCE , as you can run the snippet it works great, but there is a problem in inserting the content into the editor.
tempGroups and temp variables would be created in the back-end so it is impossible to use them statically. So I wrote the code below to insert content of each item into editor on selecting each item.
But the problem is with selecting any item, it inserts the last content value :
<p>Content44</p>
for simplification I've changed the inserting method with an alert.
Any help would be appreciated.
var tempGroups = ['Group1', 'Group2', 'Group3', 'Group4'];
var temp = [{
group: 'Group1',
title: 'Title1',
content: '<p>Content1</p>'
}, {
group: 'Group1',
title: 'Title1-1',
content: '<p>Content11</p>'
}, {
group: 'Group2',
title: 'Title2',
content: '<p>Content2</p>'
}, {
group: 'Group2',
title: 'Title2-1',
content: '<p>Content22</p>'
}, {
group: 'Group3',
title: 'Title3-1',
content: '<p>Content33</p>'
}, {
group: 'Group4',
title: 'Title4',
content: '<p>Content4</p>'
}, {
group: 'Group4',
title: 'Title4-1',
content: '<p>Content44</p>'
}];
var tempGroupName;
var menuItems = [];
function createTempMenu(editor) {
for (i = 0; i < tempGroups.length; i++) {
var tempArray = [];
tempArray[i] = [];
tempGroupName = tempGroups[i];
for (j = 0; j < temp.length; j++) {
if (temp[j].group == tempGroupName) {
// ######################################################
// The problem is here
var cc = temp[j].content;
tempArray[i].push({
text: temp[j].title,
onclick: function() {
alert(cc);
}
});
// ######################################################
}
}
menuItems[i] = {
text: tempGroupName,
menu: tempArray[i]
};
}
return menuItems;
}
tinymce.init({
selector: "textarea",
toolbar1: "UseTemplates ",
setup: function(editor) {
editor.addButton('UseTemplates', {
type: 'menubutton',
text: 'usetemplates',
icon: false,
menu: createTempMenu(editor)
});
}
});
tinyInit();
<script src="//cdn.tinymce.com/4/tinymce.min.js"></script>
<textarea>Editor</textarea>
回答1:
Your issue is that cc
is not what you think it is based on variable scope and how closures work in JavaScript. Luckily there is an easy way to avoid the joy of scope and closure for this issue - custom properties on buttons and toolbar items.
When you create each option to put in the array you can create custom properties for the JavaScript object. In the code below note how I create a custom content
property on the object that is pushed onto the array? I can then use this.settings.<propname>
to get that property when the option is selected.
// ######################################################
// The problem is here
//JavaScript scope/closure issue - cc is not what you think it is!
//var cc = temp[j].content;
tempArray[i].push({
text: temp[j].title,
content: temp[j].content, //This is a custom property on the object!
onclick: function() {
alert(this.settings.content);
}
});
// ######################################################
In my testing this resolved the issue - here is a TinyMCE Fiddle that shows this in action: http://fiddle.tinymce.com/Pqfaab
来源:https://stackoverflow.com/questions/35803619/adding-custom-dropdown-menu-to-tinymce-and-insert-dynamic-contents