Editor web WYSIWYG mínimo con Document. designMode

Tiempo de ejecución: 30 minutos. Empezar

Autor: mdotz
Views Total: 1,055
Sitio oficial: Ir a la web
Actualizado: January 19, 2018
Licencia: MIT

Vista prévia

Editor web WYSIWYG mínimo con Document. designMode

Descripción

Un mínimo limpio Editor de HTML WYSIWYG construido usando Document. designMode y documento. execCommand .

Funcionamiento

Este editor web requiere Font awesome para proporcionar los iconos de los controles del editor.

<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

Cree los controles para el editor.

<div class="bar" id="bar">

<div class="row">


<a href="#" class="far-left std" data-command='bold'><i class="fa fa-bold" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='italic'><i class="fa fa-italic" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='underline'><i class="fa fa-underline" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='justifyLeft'><i class="fa fa-align-left" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='justifyCenter'><i class="fa fa-align-center" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='justifyRight'><i class="fa fa-align-right" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='justifyFull'><i class="fa fa-align-justify" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='insertOrderedList'><i class="fa fa-list-ol" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='insertUnorderedList'><i class="fa fa-list-ul" aria-hidden="true"></i></a>


<a href="#" class="std" class="far-right" data-command='src'><i>abc</i></a>

</div>

<div class="row">


<a href="#" class="std" data-command='undo'><i class="fa fa-undo" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='redo'><i class="fa fa-repeat" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='formatBlock'><i class="fa fa-header" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='indent'><i class="fa fa-indent" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='outdent'><i class="fa fa-outdent" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='subscript'><i class="fa fa-subscript" aria-hidden="true"></i></a>


<a href="#" class="std" data-command='superscript'><i class="fa fa-superscript" aria-hidden="true"></i></a>


<a href="#" id="font"><i class="fa fa-font" aria-hidden="true"></i></a>


<a href="#" class="picker" id="fore"><i class="fa fa-font fore" aria-hidden="true"></i></a>


<a href="#" class="picker" id="back"><i class="fa fa-font back" aria-hidden="true"></i></a>

</div>

<div id="color-row" class="hidden active">


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>


<a href="#" class="ext"><i class="fa fa-circle" aria-hidden="true"></i></a>

</div>

<div id="font-row" class="hidden active">


<a href="#" class="fill"></a>


<a href="#" class="fill"></a>


<a href="#" class="ext">1</a>


<a href="#" class="ext">2</a>


<a href="#" class="ext">3</a>


<a href="#" class="ext">4</a>


<a href="#" class="ext">5</a>


<a href="#" class="ext">6</a>


<a href="#" class="ext">7</a>


<a href="#" class="fill"></a>

</div>
</div>

Cree un iframe para el contenido editable.

<iframe id="editor" name="editor">
</iframe>

El CSS para el editor.

.bar {

background-color: #9ca2b1;

flex: 0.15;

border-radius: 10px 10px 0 0;

display: flex;

flex-flow: column
}

.bar .row {

flex: 1;

display: flex;

flex-flow: row;

background-color: #b5c4ce;

border-top-left-radius: 10px;

border-top-right-radius: 10px
}

.bar .row.active a { background-color: #adb4c1 }

.bar .row a {

color: black;

flex: 0.1;

display: flex;

align-items: center;

justify-content: center;

text-align: center;

text-decoration: none;

background-color: #b5c4ce
}

.bar .row a.fill { background-color: #b5c4ce }

.bar .row a.fill:hover { background-color: #b5c4ce }

.bar .row a:hover { background-color: #c7dfdd }

.bar .row a.far-left { border-top-left-radius: 10px }

.bar .row a.far-right { border-top-right-radius: 10px }

.bar .row a.ext { font-size: 2vw }

.bar .row a.active {

background-color: #adb4c1;

border-top-right-radius: 10px;

border-top-left-radius: 10px
}

.bar .row a i { font-size: 1.6vw }

.bar .row a i.fa.fa-font.fore {

color: #ff6961;

text-decoration: underline
}

.bar .row a i.fa.fa-font.back { background: #779ecb }

#editor {

background-color: #fff;

flex: 0.85;

padding: 1vw;

border: none
}

.hidden { display: none }

El guión principal.

editor.document.designMode = 'On';

const colors = ['#ffffff' ,'#d3d3d3' ,'#000000','#c00000','#ff0000',








'#ffc000','#ffff00','#92d050',








'#00b050', '#00b0f0'];
let foreColorState = false;
let fontSizeAnchors = document.getElementById('font-row').getElementsByTagName('a');
let colorIcons =





document.getElementById('color-row').getElementsByTagName('i');
let bar = document.getElementById('bar');
let fontRow = document.getElementById('font-row');
let colorRow = document.getElementById('color-row');
let edit = document.getElementById('editor');
let barStyle = getComputedStyle(bar);
let editStyle = getComputedStyle(edit);
let foreAnchor = document.getElementById('fore');
let backAnchor = document.getElementById('back');
let fontAnchor = document.getElementById('font');
let anchors = [foreAnchor, backAnchor, fontAnchor];

// For determining fore/back color bar option is enabled
foreAnchor.addEventListener('click', function(e){

foreColorState = true;
});

backAnchor.addEventListener('click', function(e){

foreColorState = false;
});

Los controladores de la tercera barra.

for(let i = 0; i < fontSizeAnchors.length; i++){

fontSizeAnchors[i].addEventListener('click', e => {


editor.document.execCommand('fontSize', false, i+1);

});
}

for(let i = 0; i < colors.length; i++){

colorIcons[i].style.color = colors[i];

colorIcons[i].style.fontSize = '3vw';

colorIcons[i].parentNode.addEventListener('click', function(e){


let command = foreColorState ? 'foreColor' : 'hiliteColor';


editor.document.execCommand(command, false, colors[i]);

})
}

El controlador de eventos de anclaje de fuente.

fontAnchor.addEventListener('click', function(e){


if(colorRow.classList.contains('hidden')){


toggleBarFlex();


toggleRow(fontRow);

}

else{


hideRow(colorRow);


toggleRow(fontRow);

}


if(fontRow.classList.contains('hidden')){


toggleActiveAnchor(null);

}

else {


toggleActiveAnchor(fontAnchor);

}
});

El controlador de eventos de anclaje de color.

let previousTarget;

[].forEach.call(document.getElementsByClassName('picker'), v => {

v.addEventListener('click', function(e) {




if((previousTarget == null || previousTarget === e.currentTarget)




|| colorRow.classList.contains('hidden')){





if(fontRow.classList.contains('hidden')){






toggleBarFlex();






toggleRow(colorRow);





}





else {






hideRow(fontRow);






toggleRow(colorRow);





}


}



if(colorRow.classList.contains('hidden')){



toggleActiveAnchor(null);


}


else{



if(foreColorState){




toggleActiveAnchor(foreAnchor);



}



else {




toggleActiveAnchor(backAnchor);



}


}



previousTarget = e.currentTarget;

});
});

function toggleBarFlex(){

edit.style.flex = editStyle.flexGrow == 0.85 ? 0.775 : 0.85;

bar.style.flex = barStyle.flexGrow == 0.15 ? 0.225 : 0.15;
}
function toggleRow(row){

row.classList.toggle('row');

row.classList.toggle('hidden');
}
function hideRow(row){

row.classList.add('hidden');

row.classList.remove('row');
}

function toggleActiveAnchor(activeAnchor){

anchors.forEach(a => {


a.classList.remove('active');

})

if(activeAnchor != null){


activeAnchor.classList.add('active');

}
}

El controlador de eventos de anclaje estático.

[].forEach.call(document.getElementsByClassName('std'), v => {

v.addEventListener('click', function(e){



//Using currentTarget instead of target due to propagation


let command = e.currentTarget.getAttribute('data-command');



switch(command){



case 'src':




let child = e.currentTarget.childNodes[0];




child.innerHTML = child.textContent === 'abc' ? '&lt/&gt' : 'abc';




//TODO




break;



case 'formatBlock':




editor.focus();




editor.document.execCommand(command, false, 'H1');




editor.focus();




break;



default:




editor.focus();




editor.document.execCommand(command, false, null);




editor.focus();


}

})
});

Te puede interesar: