I'm trying to create tooltips with title attribute and jQuery but can't find method to show dynamically added element.
HTML
some page
CSS
.tooltip {
…
display: none; /* I's needed for hard coded tooltips */
…
}
jQuery
$(function () {
if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
//That's it. My tooltip has been created, but it has not been shown
$(el + ' .tooltip').show('fast');
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
$(el + ' .tooltip').hide('fast').remove();
el.prop('title', el.data('title'));
}
);
}
});
As mentioned by others, $(el + ' .tooltip').show('fast'); is probably wrong.
The el is an object, not a string to concat', one way is to use el.find('.tooltip').show().
The other way is to use the context option: $('.tooltip', el).show();
You need to have correct code to find new element:
$('.tooltip', el).show('fast');
Your current one probably endup searching for something like [object] .tooltip or similar string depending on how JavaScript decides to convert HTML element to string.
As others have mentioned el.find('.tooltip').show() and el.find('.tooltip').hide().remove(); solve the problem.
Also, in HandlerOut function, you el was not declared. Fiddle here
$(function () {
//if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
//That's it. My tooltip has been created, but it has not been shown
el.find('.tooltip').show()
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
var el = $(this);
el.find('.tooltip').hide().remove();
el.prop('title', el.data('title'));
}
);
//}
});
Related
I'm just learning JS and jQuery, so I can not reduce the normal code is shown below:
var menuBtn = '#menu',
classMenuOpen = 'side_menu_open',
aboutBtn = '#about',
classAboutOpen = 'side_about_open',
dateBtn = '#date',
classDateOpen = 'side_date_open',
closeBtn = '.header__menu a, .close';
// Menu Side
$(menuBtn).on('click', function() {
$('html').toggleClass(classMenuOpen);
});
$(closeBtn).not(menuBtn).on('click', function() {
$('html').removeClass(classMenuOpen);
});
// About Side
$(aboutBtn).on('click', function() {
$('html').toggleClass(classAboutOpen);
});
$(closeBtn).not(aboutBtn).on('click', function() {
$('html').removeClass(classAboutOpen);
});
// Date Side
$(dateBtn).on('click', function() {
$('html').toggleClass(classDateOpen);
});
$(closeBtn).not(dateBtn).on('click', function() {
$('html').removeClass(classDateOpen);
});
I would like to write a loop (example below) , but knowledge is not enough. I hope someone can help, thanks in advance ;)
['menu', 'about', 'date'].forEach((selector) => {
$('.' + selector + ' .scrollbar-inner').scrollbar({
onScroll: function(y, x){
$('.' + selector + ' .scrollbar-inner').toggleClass('scroll-shadow', y.scroll >= 5);
}
});
});
maybe something like this:
// wrap in IIFE for scope containment
(function($) {
// Setup button keys
const buttons = ['menu', 'about', 'date'];
// click handler
const createClickHandler = value => {
// set loop variables
let selector = `#${value}`
, className = `side_${value}_open`;
// create event triggers
$(selector).on('click', e => $('html').toggleClass(className));
$('.header__menu a, .close').not(selector).on('click', e => $('html').removeClass(className))
};
// iterate keys and apply handler method
buttons.forEach(createClickHandler);
})(jQuery);
Here is the loop you are looking for!
In the forEach() loop you are looping through the array of strings, component holds the string element (so here 'menu', 'about', etc...). Then inside the loop's body set two variables:
selector is the selector string
classOpen is the class name of an element you have associated with the component
Then you basically write the same code using only those two variables instead of writing the code three times with set strings.
let closeBtn = '.header__menu a, .close'
['menu', 'about', 'date'].forEach(function(component) {
let selector = '#' + component;
let classOpen = '.side_' + component + '_open';
$(selector).on('click', function() {
$('html').toggleClass(classOpen);
});
$(closeBtn).not(selector).on('click', function() {
$('html').removeClass(selector);
});
});
I have over 100 videos and I use a function to highlight the links clicked. The code thought is very long and I feel like there must be a way to simplify it into a for loop or something. Any idea?
var vid_all0 = $('#vid_link0, #vidtop_link0, .vidtop_link0, #vidmob_link0, #link0'); //cache selector
vid_all0.click(function () {
$('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link], .vidtop_link0').css('background-color', 'inherit');
vid_all0.css('background-color', '#A9CDEB'); //change color of all elements
$('.vidtop_link0').css('background-color', 'inherit');
});
var vid_all1 = $('#vid_link1, #vidtop_link1, #vidmob_link1,#link10'); //cache selector
vid_all1.click(function () {
$('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link]').css('background-color', 'inherit');
vid_all1.css('background-color', '#A9CDEB'); //change color of all elements
});
var vid_all2 = $('#vid_link2, #vidtop_link2, #vidmob_link2,#link19'); //cache selector
vid_all2.click(function () {
$('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link]').css('background-color', 'inherit');
vid_all2.css('background-color', '#A9CDEB'); //change color of all elements
});
...
it goes up to 15
Give all those elements the same class, then use all elements with that class like
$(".vidtop").on("click", function()
{
// Do something with their CSS
});
If you can't modify your HTML with a class, something like this should work:
for (var i=1; i=99; i==;) {
$(vid_all + i).click(function () {
$(this).find('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link]').css('background-color', 'inherit');
});
}
I'm not sure if I understood your code correctly, but this would seem to be a simpler version:
function doStuff(links, additional) {
links.click(function() {
$('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link]' + (additional ? "," + additional : "")).css('background-color', 'inherit');
links.css('background-color', '#A9CDEB');
if (additional) {
additional.css('background-color', 'inherit');
}
});
}
// vid_all0
doStuff($('#vid_link0, #vidtop_link0, .vidtop_link0, #vidmob_link0, #link0'), $('.vidtop_link0'));
// vid_all1
doStuff($('#vid_link1, #vidtop_link1, #vidmob_link1,#link10'));
// vid_all2
doStuff($('#vid_link2, #vidtop_link2, #vidmob_link2,#link19'));
// etc.
I've searched around I cannot find the answer to this. In my code, a link is created inside of a div and given an onclick value to pass an argument to a function. I cannot figure out why it will not fire.
var imgCount = 0;
var curImg;
function resetImg(target) {
alert(target);
}
$(".add").click(function () {
imgCount = imgCount + 1;
curImg = "theImg" + imgCount;
//Here we add the remove link
$('#links')
.append('Call Function');
$('.dynamic').css('display', 'block');
});
Here's the fiddle:
http://jsfiddle.net/stewarjs/4UV7A/
I've tried using .click() when creating the link, but the argument being passed needs to be unique to each link. I've tried grabbing $(this).attr("id") but the value comes back undefined.
Thanks for any and all help.
Jeff
Rather than try to mangle HTML into JavaScript, I suggest you use the jQuery methods already available to you.
$('#links')
.append($("<a>").attr('href', '#').on('click', function () { resetImg(curImg);
}).addClass('dynamic').text('Call Function'));
http://jsfiddle.net/ExplosionPIlls/4UV7A/1/
remove javascript: from onclick, it should like like this: onclick="resetImg(\'' + curImg + '\');"
There's always a way to get rid of onclick handlers. Here's how I'd do it:
var image_count = 0;
$('#links').on('click', '.dynamic', function(e) {
e.preventDefault()
alert($(this).data('image'));
});
$('.add').click(function () {
$('<a />', {
'href': '#',
'data-image': 'theImg' + (++image_count),
'class': 'dynamic',
'text': 'Call function'
}).appendTo('#links');
});
Demo: http://jsfiddle.net/4UV7A/4/
I try to convert a div tag into something I can drag and drop in CKEditor (as asked in another question).
Do you know how I can trigger the event when someone switches between source view and WYSIWYG mode?
I think this is what you are looking for:
CKEDITOR.on('instanceCreated', function(e) {
e.editor.on('mode', function(e){
// Do your stuff here
alert(e.editor.mode);
});
});
If you mean, you want to capture source mode changes , then you could try something like this:
//add this to your CKeditor’s config.js
$('textarea.cke_source').live('keyup', function() {
$(this)
.closest('.cke_wrapper')
.parent()
.parent()
.prev()
.ckeditorGet()
.fire('change');
});
This discussion might help as well: ckEditor
Hope it helps
CKEditor onChange plugin:
Get a notification (new event) whenever the content of CKEditor changes.
http://ckeditor.com/addon/onchange
I think you should write a plugin to make a fake element for the wysiwyg-view.
Ckeditor is able to recognize elements that need to be replaced with fake-elements.
I made a start for you:
(function() {
CKEDITOR.plugins.add('myPlugin', {
requires : ['fakeobjects'],
init: function(editor) {
var me = this;
var pluginName = 'myPlugin';
editor.addCommand(pluginName, new CKEDITOR.dialogCommand(pluginName));
editor.addCss( // your custom css for your placeholder here
'div.myPluginElement' +
'{' +
'border: 1px solid #a9a9a9;' +
'width: 70px;' +
'height: 50px;' +
'}'
);
},
afterInit : function(editor) {
var dataProcessor = editor.dataProcessor,
dataFilter = dataProcessor && dataProcessor.dataFilter;
if (dataFilter) {
dataFilter.addRules({
elements : {
div : function(element) {
if (typeof element.attributes['class'] !== 'undefined' && element.attributes['class'].indexOf('myPluginElement') != -1)
return editor.createFakeParserElement(element, 'myPluginElement', 'div', false);
else return;
}
}
});
}
}
});
})();
Below you can see that I store the results of the jquery selector in an array. I then use this array to perform other functions. This example here doesn't seem to work, it's behaving as if the var/array is a live selector, not the results when they were instantiated.
function flipIt(elementId){
if (window.jQuery){
var thisVisibleArray = $('#' + elementId + ' div:visible');
var thisInvisibleArray = $('#' + elementId + ' > div:visible');
$(thisInvisibleArray).slideDown("fast");
$(thisVisibleArray).slideUp("fast");
/*
if ($('#flip1').is(":visible")){
$('#flip1').slideUp("fast", function(){
$('#flip2').slideDown();
});
} else {
$('#flip2').slideUp("fast", function(){
$('#flip1').slideDown();
});
}*/
}
}
In order to select the invisible div elements you have to use not and not ">". And also the 2 variables you defined are already jquery element array so you dont have to use $(). Try this
function flipIt(elementId){
if (window.jQuery){
var thisVisibleArray = $('#' + elementId + ' div:visible');
var thisInvisibleArray = $('#' + elementId + ' div:not(:visible)');
thisInvisibleArray.slideDown("fast");
thisVisibleArray.slideUp("fast");
/*if ($('#flip1').is(":visible")){
$('#flip1').slideUp("fast", function(){
$('#flip2').slideDown();
});
} else {
$('#flip2').slideUp("fast", function(){
$('#flip1').slideDown();
});
}*/
}
}
You are storing the selected elements in a variable, and then you are trying to get a jQuery object out of another jQuery object. Just do:
thisInvisibleArray.slideDown("fast");
thisVisibleArray.slideUp("fast");
Also, they are not arrays, but jQuery objects.