CKEditor - For each attribute with class name do something - javascript

I'm trying to get the value of an attribute for each element with a class name.
Here is my code:
var textareaId;
$(document).ready(function () {
textareaId = $('#tiny_mce_block').find('textarea').attr('id'); //
ckeditor_init();
});
function ckeditor_init() {
CKEDITOR.replace(textareaId, {
allowedContent: true,
on: {
instanceReady: function (evt) {
var editor = this;
var data = editor.getData();
var body = $(editor.document.getBody());
jwplayer("video_block_sous_titres").onTime(function (event) {
$.each(**SELECT CLASS .ST**, function () { // HOW SELECT ELEMENTS WHERE THE CLASS IS 'st'
var d = SELECT DATA-TIME-START ; // HOW GET CONTENT OF ATTRIBUTE NAMED 'data-time-start'
var f = SELECT DATA-TIME-END; // HOW GET CONTENT OF ATTRIBUTE NAMED 'data-time-end'
if (d <= event.position && event.position <= f) {
if ($(this).attr("class") !== "active") {
$(".st").removeClass("active"); // HOW REMOVE THE CLASS 'active'
$(this).addClass("active"); // HOW ADD THE CLASS 'active'
}
} else {
$(this).removeClass("active"); // HOW REMOVE THE CLASS 'active'
}
});
});
}
}
});
}
In my textarea I have this:
<span class="st" id="1" data-time-start="0.29" data-time-end="1.259" data-time-moy="0.1938">mardi </span>
<span class="st" id="2" data-time-start="2.048" data-time-end="5.406" data-time-moy="0.10832258064516">qualité sécurité efficacité </span>
First question :
In my loop where JWPlayer is called, How can I select for each element which have Class .st, the value of attribute named data-time-start and data-time-end ?
Second question:
After that, How to add or remove class active to this .st (with which method ?) ?
I tried to get the content of attribute like that but no way:
var st = el.find('#20');
console.log(st.getAttribute('data-time-start'));
MY FIDDLE : http://jsfiddle.net/B4yGJ/415/
Thanks for your help !

I resolved my problem with this :
function jwplayer_underligne_st() {
jwplayer("video_block_sous_titres").onTime(function (evt) {
//var st = $(CKEDITOR.instances[textareaId].window.getFrame().$).contents().find('.word');
var st = $(CKEDITOR.instances[textareaId].window.getFrame().$).contents().find('.st');
$.each(st, function () {
$this = $(this);
var d = $this.attr("data-time-start");
var f = $this.attr("data-time-end");
if (d <= evt.position && evt.position <= f) {
if ($this.attr("class") !== "active") {
$this.addClass("active");
}
} else {
$this.removeClass("active");
}
});
});
}

Related

how to add event listener to appened content on javascript

i have created my own jquery because i need only these 4 functions,
everything is working well until i click append.
i tried document.getElementsByTag because it returns live htmlcollection but didnt work
function $(s)
{
var el;
if (s instanceof HTMLElement) { el = [s]; } else { el = document.querySelectorAll(s); }
const obj =
{
elm : el,
show : function() { var i = obj.elm.length; while (i--) { obj.elm[i].style.display = ""; } },
hide : function() { var i = obj.elm.length; while (i--) { obj.elm[i].style.display = "none"; } },
on : function(ev,cb) { var i = obj.elm.length; while(i--) { obj.elm[i].addEventListener(ev,cb); } },
append : function(cn) { var i = obj.elm.length; while(i--) { obj.elm[i].innerHTML += cn; } }
}
return obj
}
<ul>
<li>Click to hide</li>
<li>Click to hide</li>
<li>Click to hide</li>
<li>Click to hide</li>
</ul>
<button id="sh">Show</button>
<button id="ap">Append</button>
<script>
document.addEventListener("DOMContentLoaded", function() {
$("li").on("click", function() {
$("li").hide();
});
$("#sh").on("click", function() {
$("li").show();
});
$("#ap").on("click", function() {
$("ul").append("<li>X<li/>");
});
});
</script>
I would change your code a bit (innerHTML += is a bad practice, it breaks the current listeners).
First change your click listener:
$("#ap").on("click", function() {
const li = document.createElement('li');
li.innerText = 'X';
// add the event listeners to the li element
li.addEventListener(...)
// append it
$("ul").append(li);
});
Now change this obj.elm[i].innerHTML += cn; to obj.elm[i].insertAdjacentElement('beforend', cn). Notice that in this version, cn is an HTML element and NOT a string, and it's using insertAdjacentElement instead of innerHTML += so you don't lose the previous event listeners.

Auto Scaling Image Annotation

Scalize is a jQuery plugin used for adding custom markers (hotspots) with custom popovers and animations to containers or images.
But now When I click one by one on pointer it show all one by one But I am trying to show only one so when click another pointer will close the other which already opened.
Here is my EXAMPLE
(function(jQuery) {
"use strict";
//----------------------------------------//
// Variable
//----------------------------------------//
var variable = {
width : 0,
height : 0,
selector : '.item-point',
styleSelector : 'circle',
animationSelector : 'pulse2',
animationPopoverIn : 'flipInY',
animationPopoverOut : 'flipOutY',
onInit : null,
getSelectorElement : null,
getValueRemove : null
}
//----------------------------------------//
// Scaling
//----------------------------------------//
var scaling = {
settings : null,
//----------------------------------------//
// Initialize
//----------------------------------------//
init: function(el, options){
this.settings = jQuery.extend(variable, options);
this.event(el);
scaling.layout(el);
jQuery(window).on('load', function(){
scaling.layout(el);
});
jQuery(el).find('.target').on('load', function(){
scaling.layout(el);
});
jQuery(window).on('resize', function(){
scaling.layout(el);
});
},
//----------------------------------------//
// Event
//----------------------------------------//
event : function(elem){
// Set Style Selector
if ( this.settings.styleSelector ) {
jQuery(this.settings.selector).addClass( this.settings.styleSelector );
}
// Set Animation
if ( this.settings.animationSelector ) {
if( this.settings.animationSelector == 'marker' ){
jQuery(this.settings.selector).addClass( this.settings.animationSelector );
jQuery(this.settings.selector).append('<div class="pin"></div>')
jQuery(this.settings.selector).append('<div class="pulse"></div>')
}else{
jQuery(this.settings.selector).addClass( this.settings.animationSelector );
}
}
// Event On Initialize
if ( jQuery.isFunction( this.settings.onInit ) ) {
this.settings.onInit();
}
// Content add class animated element
jQuery(elem).find('.content').addClass('animated');
// Wrapper selector
jQuery(this.settings.selector).wrapAll( "<div class='wrap-selector' />");
// Event Selector
jQuery(this.settings.selector).each(function(){
// Toggle
jQuery('.toggle', this).on('click', function(e){
e.preventDefault();
jQuery(this).closest(scaling.settings.selector).toggleClass('active');
// Selector Click
var content = jQuery(this).closest(scaling.settings.selector).data('popover'),
id = jQuery(content);
if(jQuery(this).closest(scaling.settings.selector).hasClass('active') && !jQuery(this).closest(scaling.settings.selector).hasClass('disabled')){
if ( jQuery.isFunction( scaling.settings.getSelectorElement ) ) {
scaling.settings.getSelectorElement(jQuery(this).closest(scaling.settings.selector));
}
id.fadeIn(500,function(){
if( getBrowserName() == "Safari" ){
setTimeout(function(){
id.removeClass('flipInY');
},125);
}
});
scaling.layout(elem);
id.removeClass(scaling.settings.animationPopoverOut);
id.addClass(scaling.settings.animationPopoverIn);
}else{
if(jQuery.isFunction( scaling.settings.getValueRemove )){
scaling.settings.getValueRemove(jQuery(this).closest(scaling.settings.selector));
}
id.removeClass(scaling.settings.animationPopoverIn);
id.addClass(scaling.settings.animationPopoverOut);
id.delay(500).fadeOut();
}
});
// Exit
var target = jQuery(this).data('popover'),
idTarget = jQuery(target);
idTarget.find('.exit').on('click', function(e){
e.preventDefault();
// selector.removeClass('active');
jQuery('[data-popover="'+ target +'"]').removeClass('active');
idTarget.removeClass(scaling.settings.animationPopoverIn);
idTarget.addClass(scaling.settings.animationPopoverOut);
idTarget.delay(500).fadeOut();
});
});
},
//----------------------------------------//
// Layout
//----------------------------------------//
layout : function(elem){
// Get Original Image
var image = new Image();
image.src = elem.find('.target').attr("src");
// Variable
var width = image.naturalWidth,
height = image.naturalHeight,
getWidthLess = jQuery(elem).width(),
setPersenWidth = getWidthLess/width * 100,
setHeight = height * setPersenWidth / 100;
// Set Heigh Element
jQuery(elem).css("height", setHeight);
// Resize Width
if( jQuery(window).width() < width ){
jQuery(elem).stop().css("width","100%");
}else{
jQuery(elem).stop().css("width",width);
}
// Set Position Selector
jQuery(this.settings.selector).each(function(){
if( jQuery(window).width() < width ){
var getTop = jQuery(this).data("top") * setPersenWidth / 100,
getLeft = jQuery(this).data("left") * setPersenWidth / 100;
}else{
var getTop = jQuery(this).data("top"),
getLeft = jQuery(this).data("left");
}
jQuery(this).css("top", getTop + "px");
jQuery(this).css("left", getLeft + "px");
// Target Position
var target = jQuery(this).data('popover'),
allSize = jQuery(target).find('.head').outerHeight() + jQuery(target).find('.body').outerHeight() + jQuery(target).find('.footer').outerHeight();
jQuery(target).css("left", getLeft + "px");
jQuery(target).css("height", allSize + "px");
if(jQuery(target).hasClass('bottom')){
var getHeight = jQuery(target).outerHeight(),
getTopBottom = getTop - getHeight;
jQuery(target).css("top", getTopBottom + "px");
}else if(jQuery(target).hasClass('center')){
var getHeight = jQuery(target).outerHeight() * 0.50,
getTopBottom = getTop - getHeight;
jQuery(target).css("top", getTopBottom + "px");
}else{
jQuery(target).css("top", getTop + "px");
}
jQuery('.toggle', this).css('width', jQuery(this).outerWidth());
jQuery('.toggle', this).css('height', jQuery(this).outerHeight());
// Toggle Size
if(jQuery(this).find('.pin')){
var widthThis = jQuery('.pin', this).outerWidth(),
heightThis = jQuery('.pin', this).outerHeight();
jQuery('.toggle', this).css('width', widthThis);
jQuery('.toggle', this).css('height', heightThis);
}
});
}
};
//----------------------------------------//
// Scalize Plugin
//----------------------------------------//
jQuery.fn.scalize = function(options){
return scaling.init(this, options);
};
}(jQuery));
function getBrowserName() {
var name = "Unknown";
if(navigator.userAgent.indexOf("MSIE")!=-1){
name = "MSIE";
}
else if(navigator.userAgent.indexOf("Firefox")!=-1){
name = "Firefox";
}
else if(navigator.userAgent.indexOf("Opera")!=-1){
name = "Opera";
}
else if(navigator.userAgent.indexOf("Chrome") != -1){
name = "Chrome";
}
else if(navigator.userAgent.indexOf("Safari")!=-1){
name = "Safari";
}
return name;
}
Add this to your initialisation:
getSelectorElement: function(el) {
$('.item-point.active').not($(el)[0]).find('.toggle').click();
}
This hooks into the getSelectorElement method in the Scalize plugin and triggers a click on any active (open) elements that don't match the most recently clicked item.
Add it like so:
$(document).ready(function(){
$('.scalize').scalize({
styleSelector: 'circle',
animationPopoverIn: 'fadeIn',
animationPopoverOut: 'fadeOut',
animationSelector: 'pulse2',
getSelectorElement: function(el) {
$('.item-point.active').not($(el)[0]).find('.toggle').click();
}
});
});
Note, because this is hooking into existing methods in the plugin it's a little safer (no unpredictable side effects, plus you get the intended transition out on the disappearing elements). Fiddle.
I've modified your jsFiddle to work.
TL;DR: Anytime an point is clicked, if there are other active siblings, loop over them and hide their popups.
It isn't a pretty way of doing it but it is working in the Fiddle.
$('.scalize').on('click', '.item-point', (function() {
$(this).siblings('.item-point.active').each(function() {
var popover = $(this).data('popover');
$(popover).removeClass('fadeIn').css({
'display': 'none'
});
$(this).removeClass('active');
});
}));

how to use a loop within a functions parameter and log the result to the console

The goal I am trying to achieve is to use jQuery to collect, all the CLASS css stylings of any HTML page and then loop through each of the classes and gather the height, width, top and left of each class, which I'll then put into an Array and log it to the console.
Below is where I am currently at with the code. I'm able to gather all the page classes, but struggling to loop through them to give me the height, width, top and left of each class. Below is the code, would anyone be able to guide me in the right direction or possible give an example on how to build it?. Any help will be appreciated :)
$(document).ready(function() {
// VARIABLES
var allClassNames = [];
var eachClassName = "";
// GET CLASS NAMES FROM THE HTML PAGE
$('[class]').each(function eachClassName(){
$.each($(this).attr('class').split(' '), function(i, className) {
if (className.length && $.inArray(className, allClassNames) === -1) {
allClassNames.push(className);
}
});
});
// GET THE CSS STYLING FOR EACH CLASS
function getStyleRuleValue(style, selector) {
for (var i = 0; i < document.styleSheets.length; i++) {
var mysheet = document.styleSheets[i];
var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
for (k = 0; k < allClassNames.length; k++) {
console.log(allClassNames[k]);
}
for (var j = 0; j < myrules.length; j++) {
if (myrules[j].selectorText && myrules[j].selectorText.toLowerCase() === selector) {
return myrules[j].style[style];
}
}
}
};
// I'M TRYING TO LOOP THROUGH THE CLASSES WHERE IT SAYS .TWO??
console.log( getStyleRuleValue('top', '.two') );
});
Do not mix jQuery and JavaScript pure code, if you are using jQuery use its methods:
HTML Code:
<div class="div1 value1"></div>
<div class="div1 value2"></div>
<div class="div1 value3"></div>
CSS Code:
.value1{
top: 100px;
}
.value2{
top: 200px;
}
.value3{
top: 300px;
}
jQuery Code:
function getStyleRuleValue(style, selector){
$("." + selector).each(function(){
console.log( $(this).css(style) );
});
}
getStyleRuleValue("top", "div1");
// 100px
// 200px
// 300px
jsfiddle
EDIT:
If you want to use the allClassNames Array with all the page classes (You do not need this Array to iterate into all page elements):
var allClassNames = [];
$("[class]").each(function eachClassName(){
$.each($(this).attr("class").split(" "), function(i, className) {
if (className.length && $.inArray(className, allClassNames) === -1) {
allClassNames.push(className);
}
});
});
$("." + allClassNames.join(",.")).each(function(){
console.log( $(this).css(['top', 'left', 'width', 'height']) );
});
jsfiddle
I'd start by building a map of selectors to styles, based on the stylesheets, and then use that to look up each of the classes I found on the document.
function getStyles() {
var allRules = {};
var selectorIndex = {};
// This will map each individual class to a selector that mentions it
// i.e. if you have a selector like ".top a", this will create two entries, one for ".top" and
// one for "a". Each entry will point to the string ".top a", which can then be used to look up
// the rule in the allRules map.
var indexSelectors = function (selectorText) {
if(typeof selectorText === "string" && selectorText.length) {
$.each(selectorText.split(' '), function (i, sel) {
var currentSelectors = selectorIndex[sel];
if (typeof currentSelectors === 'undefined') {
currentSelectors = [];
}
currentSelectors.push(selectorText);
selectorIndex[sel] = currentSelectors;
});
}
};
// Make a map of all top/left/width/height styles based on the selectors. This will be a "last one
// wins" map -- later entries will overwrite earlier ones. If you don't want "last one wins," you
// can use the array.push strategy that the indexSelectors function uses.
var extractStyles = function (i, rule) {
indexSelectors(rule.selectorText);
if(rule.style) {
var topStyle = rule.style['top'];
var leftStyle = rule.style['left'];
var widthStyle = rule.style['width'];
var heightStyle = rule.style['height'];
// only make an entry if there's at least one non-empty style in the list we're interested in
if(topStyle.length || leftStyle.length || widthStyle.length || heightStyle.length) {
allRules[rule.selectorText] = {
top: rule.style['top'],
left: rule.style['left'],
width: rule.style['width'],
height: rule.style['height']
}
}
}
};
var extractFromStyleSheet = function (i, styleSheet) {
var rules;
if (styleSheet) {
rules = styleSheet.cssRules ? styleSheet.cssRules : styleSheet.rules;
if (rules !== null) {
$.each(rules, extractStyles);
}
}
};
// build allRules dictionary
$(document.styleSheets).each(extractFromStyleSheet);
$('[class]').each(function eachClassName(){
$.each($(this).attr('class').split(' '),function(i,className) {
if (typeof className === 'string' && className.length) {
className = '.' + className;
var selectors = selectorIndex[className];
if (selectors) {
$.each(selectors, function (i, sel) {
var found = allRules[sel];
if (found) {
console.log(className, sel, found);
}
});
}
}
});
});
}
I'm not sure I completely understand what you're trying to do here, and particularly how do you want to handle CSS styles like this?
.two {
top: 12px;
}
.two a {
top: 24px;
}
Still, the code above should get you started (assuming I've correctly understood what you're looking for).

Remove tool tip from warning dialog box

I want to remove YES and NO tool tip from a custom dialog box after the dialog is displayed.
The problem is that I am unable to get the object of the YES and NO buttons by ID or attribute name due to not being able to remove the "title" attribute".
Here is what the customDialog function looks like
function dialog_customDialog(dialogType, callingWindow,msg, showThird, firstCBF, secondCBF, thirdCBF, firstText, secondText, thirdText, dialogTimeout, timeoutCBF) {
if (dialogTimeout > 0) {
yesCallback = function() {processCallback(firstCBF);};
noCallback = function() {processCallback(secondCBF);};
cancelCallback = function() {processCallback(thirdCBF);};
}
else {
yesCallback = firstCBF;
noCallback = secondCBF;
cancelCallback = thirdCBF;
}
timeoutCallback = timeoutCBF
if (showThird)
buttonSet = 3;
else
buttonSet = 2;
if (firstText) {
var ybt = document.getElementById('button_YES');
if (ybt) {
if (!yesText) yesText = ybt.innerHTML;
ybt.innerHTML = firstText;
}
}
if (secondText) {
var nbt = document.getElementById('button_NO');
if (nbt) {
if (!noText) noText = nbt.innerHTML;
nbt.innerHTML = secondText;
}
}
if (thirdText) {
var cbt = document.getElementById('button_CANCEL');
if (cbt) {
if (!cancelText) cancelText = cbt.innerHTML;
cbt.innerHTML = thirdText;
}
}
if(!dialogType) {
displayDialog(callingWindow,msg, 'questImg', 'Question',buttonSet,firstText,secondText,thirdText,dialogTimeout);
}
else if('warning' == dialogType.toLowerCase()){
displayDialog(callingWindow,msg, 'warnImg', 'Warning',buttonSet,firstText,secondText,thirdText,dialogTimeout);
}
else if('information' == dialogType.toLowerCase()){
displayDialog(callingWindow,msg, 'infoImg', 'Information',buttonSet,firstText,secondText,thirdText,dialogTimeout);
}
else if('information' == dialogType.toLowerCase()){
displayDialog(callingWindow,msg, 'errorImg', 'Error',buttonSet,firstText,secondText,thirdText,dialogTimeout);
}
else{
displayDialog(callingWindow,msg, 'questImg', 'Question',buttonSet,firstText,secondText,thirdText,dialogTimeout);
}
}
After the dialog is displayed i am trying to hide the tool tip. Here is the code.
var yesBtn= $("#button_YES");
yesBtn.removeAttr("title");
The problem is yesBtn object is empty. Here is how the HTML code for the dialog button looks like:

Mouse actions possible on all id tags on a webpage

What I want to do is, find all possible actions (click , hover, etc) on each element id on a web page.
Below is my effort towards it:
function executeInteractions($) {
for (var interaction_count = 0; interaction_count < interactions.length; interaction_count++) {
var obj = interactions[interaction_count];
for (var event_count = 0; event_count < obj.events.length; event_count++) {
(function(elem, event_name, e_count, i_count, t_i_count) {
setTimeout(function() {
elem.trigger(event_name);
var sendData = {id : elem.attr('id') , event_n: event_name }
&.post("link#",sendData)
setTimeout(function() {
}
}, 10);
if (i_count + 1 >= t_i_count) {
window.interactionsComplete = true;
}
}, 500 * i_count);
}(obj.item, obj.events[event_count], event_count, interaction_count, interactions.length));
}
}
}
function findInteractions($) {
$(document).click(function(e) {
e.preventDefault();
});
$(document).submit(function(e) {
e.preventDefault();
});
var node, toBeProcessed = new Array;
toBeProcessed.push($('body')[0]);
while (toBeProcessed.length) {
node = $(toBeProcessed.pop());
var eventObject = node.data('events');
if (eventObject) {
var events = [];
for (var e in eventObject) {
events.push(e);
}
interactions.push({
'item': node,
'events': events
});
}
var childrens = node.children();
if (childrens && childrens.length > 0) {
for (var i = 0; i < childrens.length; ++i) {
toBeProcessed.push(childrens[i]);
}
}
}
}
window.interactions = [];
When the post request is received at the server end, I get lot of null values for id.
Can someone help me out here, or may be suggest any other efficient method to capture all possible actions on id elements on a web page.
You can apply unique class to each attribute on page and then write .click()/.mouseover() JQuery event on it.
HTML:
<p class="uniqueClass">1st para</p>
<p class="uniqueClass">2nd para</p>
JQuery code:
<script>
$( ".uniqueClass" ).click(function() {
alert("Clicked");
});
</script>
For mouse over, you can use .mouseover() function like:
<script>
$( ".uniqueClass" ).mouseover(function() {
alert("Mouse Over");
});
</script>

Categories

Resources