execCommand insertHtml, outer div not inserted why? - javascript

Why is the DIV not inserted but only the IMG ?
$(document).ready(function() {
$(document).on('click', '#insertImage', function(){
/*
Why is the DIV not inserted ?
*/
var item = "<div class='resizable'><img src='http://www.rockiesventureclub.org/wp-content/uploads/2013/02/flower-icon.png'></div>";
document.execCommand('insertHTML', false,item);
})
});
see:
http://jsfiddle.net/daslicht/gU2jP/#base

Why not doing it with jQuery since you already use it??
http://jsfiddle.net/gU2jP/5/
var _$div = $('<div>'),
_$img = $("<img class='resizeable' id='myImg' src='http://imperavi.com/img/library.jpg' />");
_$div.append(_$img);
$('body').append(_$div);

The background of the Question was the following:
I just like to be able to make the added Image Float Left or Right.
Since jQueryUI automatically adds a wrapper-div around each resizeable item I thought that I need to add it somehow manually in order to assign a id to it.
doug65536 on Freenode helped me to create this solution without the need to create an additionally div manually:
We also discovered that the Fiddle wont work properly in safari
$(document).on('click', '#insertImage', function () {
document.execCommand('insertHTML', false,
"<img class='resizeable' id='myImg' src='http://imperavi.com/img/library.jpg'>");
$(".resizeable").resizable({
aspectRatio: true
}); //just a try here
$('#myImg').parent().css({
'float':'left',
'margin':'15px'
});
})
http://jsfiddle.net/daslicht/6cGbQ/
Thank you very Much !

Related

jQuery slideDown not working on element with dynamically assigned id

EDIT: I cleaned up the code a bit and narrowed down the problem.
So I'm working on a Wordpress site, and I'm trying to incorporate drop-downs into my menu on mobile, which means I have to use jQuery to assign classes and id's to my already existing elements. I have this code that already works on premade HTML, but fails on dynamically created id's.
Here is the code:
...
var menuCount = 0;
var contentCount = 0;
//find the mobile menu items
var submenus = $('[title="submenu"]');
if (submenus.length && submenus.parent('.fusion-mobile-nav-item')) {
console.log(submenus);
submenus.addClass('dropdown-title').append('<i id="dropdown-angle" class="fa fa-angle-down" aria-hidden="true"></i>');
submenus.each(function() {
$(this).attr("href", "#m" + menuCount++);
})
var content = submenus.parent().find('ul.sub-menu');
content.addClass('dropdown-content');
content.each(function() {
$(this).attr("id", "m" + contentCount++);
})
}
$(document).on('click', '.dropdown-title', function(e) {
var currentAttrValue = $(this).attr('href');
if ($(e.target).is('.d-active') || $(e.target).parent('.dropdown-title').is('.d-active')) {
$(this).removeClass('d-active');
$(currentAttrValue).slideUp(300).removeClass('d-open');
} else {
$('.dropdown-title').removeClass('d-active');
$('.dropdown-content').slideUp(300).removeClass('d-open');
$(this).addClass('d-active');
console.log($(currentAttrValue));
//THIS LINE FAILS
$(currentAttrValue).slideDown(300).addClass('d-open');
}
e.preventDefault();
});
I've registered the elements with the class dropdown-title using $(document).on(...) but I can't figure out what I need to do to register the elements with the custom ID's. I've tried putting the event callback inside the .each functions, I've tried making custom events to trigger, but none of them will get the 2nd to last line of code to trigger. There's no errors in the console, and when I console log the selector I get this:
[ul#m0.sub-menu.dropdown-content, context: document, selector: "#m0"]
0
:
ul#m0.sub-menu.dropdown-content
context
:
document
length
:
1
selector
:
"#m0"
proto
:
Object[0]
So jQuery knows the element is there, I just can't figure out how to register it...or maybe it's something I'm not thinking of, I don't know.
If you are creating your elements dynamically, you should be assigning the .on 'click' after creating those elements. Just declare the 'on click' callback code you posted after adding the ids and classes instead of when the page loads, so it gets attached to the elements with .dropdown-title class.
Check this jsFiddle: https://jsfiddle.net/6zayouxc/
EDIT: Your edited JS code works... There also might be some problem with your HTML or CSS, are you hiding your submenus? Make sure you are not making them transparent.
You're trying to call a function for a attribute, instead of the element. You probably want $(this).slideDown(300).addClass('d-active'); (also then you don't need $(this).addClass('d-active'); before)
Inside submenus.each loop add your callback listener.
As you are adding the class dropdown-title dynamically, it was not available at dom loading time, that is why event listener was not attached with those elemnts.
var menuCount = 0;
var contentCount = 0;
//find the mobile menu items
var submenus = $('[title="submenu"]');
if (submenus.length && submenus.parent('.fusion-mobile-nav-item')) {
console.log(submenus);
submenus.addClass('dropdown-title').append('<i id="dropdown-angle" class="fa fa-angle-down" aria-hidden="true"></i>');
submenus.each(function() {
$(this).attr("href", "#m" + menuCount++);
// add callback here
$(this).click( function(e) {
var currentAttrValue = $(this).attr('href');
if ($(e.target).is('.d-active') || $(e.target).parent('.dropdown-title').is('.d-active')) {
$(this).removeClass('d-active');
$(currentAttrValue).slideUp(300).removeClass('d-open');
} else {
$('.dropdown-title').removeClass('d-active');
$('.dropdown-content').slideUp(300).removeClass('d-open');
$(this).addClass('d-active');
console.log($(currentAttrValue));
$(currentAttrValue).slideDown(300).addClass('d-active');
}
e.preventDefault();
});
})
var content = submenus.parent().find('ul.sub-menu');
content.addClass('dropdown-content');
content.each(function() {
$(this).attr("id", "m" + contentCount++);
})
}
Turns out my problem is that jQuery is adding to both the mobile menu and the desktop menu, where the desktop menu is being loaded first when I search for that ID that's the one that jQuery finds. So it turns out I was completely wrong about my suspicions.

Know which user created div was clicked

I apologise if my explanation is hard to understand.
Using This Code:
names.push(newName);
var strName = newName;
var newName = document.createElement('p')
newName.setAttribute('id', newName);
document.body.appendChild(newName);
newName.innerText = strName;
$(newName).css('position','absolute')
$(newName).css('top', y);
$(newName).css('left', x);
updateXY();
The user creates a new div (with a user-inputted name) which works fine.
my problem is that i don't know how to know when one of these user-crated-and-named divs is clicked.
For example:
if the user created 2 divs, 'hello' and 'goodbye' i couldnt just use $('#hello').click(function() {}); etc. Because i wouldnt know that the user would've chose to create the div entitled 'hello'
Furthermore, the array names has all of the names of all of the divs in - if this is any help to anybody. Thankyou, and any help is appreciated
Simply add the event listener to the element as you did when styling it:
$(newName).on("click",function(){
console.log("element "+$(this).text()+" clicked");
});
JSFiddle
Or, with JS's addEventListener():
newName.addEventListener("click",function(){});
JSFiddle
Or, the old way for older browsers, onclick:
newName.onclick = function(){};
JSFiddle
You could do something like this
$(newName).on("click",function(e){
// the variable 'e' is the event of click, if we do e.toElement, we get to know who the element clicked is
var $thisDiv = $(e.toElement);
// do something with $thisDiv
});
After you create a div element, you need to initialize 'click' event on the div
<a class="js-create-div" href="#">Create Div</a>
$(document).ready(function(){
function init(){
var newUserDiv = $(".js-user-div").not(".js-inited");
newUserDiv.on("click",function(){
alert($(this).html());
});
newUserDiv.addClass("js-inited");
}
$(".js-create-div").click(function(){
$("#wrapper").append("<div class='js-user-div'>"+Math.random()+"</div>");
init();
});
});
https://jsfiddle.net/ema0nazs/

Javascript mouse over on dynamic amount of elements

My goal is on hover a p element contained inside an a tag gets bigger on hover. I have achieved this via css3 transitions, however this is not the issue.
A loop creates a variable amount of elements in the form below on each iteration.
anchorElement = "<a id='anchor" + countWide + "' class=\"boxOPT oneplustwo\" alt=\'"+ image_website +"' style=\"cursor:pointer;width:"+ itemWidth + "px"+";height:"+anchorHeight+";position:absolute;left:"+ locationLeft + "px"+";top:0.3%;\" ><p id=\"test\" class=\"popupDynamic\"> " + popupImageTitles[i] + "</p>";
anchorElement += '</a>';
I would love to be able to add a mouse in/out effect whenever the user scrolls on the relevant anchor. each p tag contains unique information that needs to be conveyed and on hover only the relevant one should react.
I dont want to it it the below way, making two each of the methods every time a new element is created above. is there a way to have the following below which will work for a dynamic amount of elements?
$("#anchor" + etc).mouseover(function() {
document.getElementById("test").style.height="1.1em";
});
$("#anchor" + etc).mouseout(function() {
document.getElementById("test").style.height="1.1em";
});
My version of suggestions. the console logs works.
.popupHighlight {
color: red;
}
..
$('.boxOPToneplustwo').mouseover(function (e) {
console.log("in");
$(e.target).next('p').addClass("popupHighlight");
});
$('.boxOPToneplustwo').mouseout(function (e) {
$(e.target).next('p').removeClass("popupHighlight");
});
What about selecting all a elements?
$('a').mouseout(function() {
//do stuff in here
});
or better yet, have a class selector:
$('.mySpecialRolloverClass').mouseover(function (e) {
$(e.target).next('p').addClass("highlight");
});
$('.mySpecialRolloverClass').mouseout(function (e) {
$(e.target).next('p').removeClass("highlight");
});
which would go hand in hand with
An anchor
and
.highlight {
color:red;
}
Here's a jsfiddle demo:
http://jsfiddle.net/8J6kM/
The #yochannah answer is correct, however if you want to add more links dynamically, you then need to use on method instead of mouseover and mouseout, otherwise it won't work. See the demo and jQuery documentation for further details.
// I assumed that links are placed inside of a container element: #links
$('#links').on('mouseover', '.mySpecialRolloverClass', function (e) {
$(e.target).next('p').addClass("highlight");
});

how to repeat same Javascript code over multiple html elements

Note: Changed code so that images and texts are links.
Basically, I have 3 pictures all with the same class, different ID. I have a javascript code which I want to apply to all three pictures, except, the code needs to be SLIGHTLY different depending on the picture. Here is the html:
<div class=column1of4>
<img src="images/actual.jpg" id="first">
<div id="firsttext" class="spanlink"><p>lots of text</p></div>
</div>
<div class=column1of4>
<img src="images/fake.jpg" id="second">
<div id="moretext" class="spanlink"><p>more text</p></div>
</div>
<div class=column1of4>
<img src="images/real.jpg" id="eighth">
<div id="evenmoretext" class="spanlink"><p>even more text</p></div>
</div>
Here is the Javascript for the id="firsttext":
$('#firstextt').hide();
$('#first, #firsttext').hover(function(){
//in
$('#firsttext').show();
},function(){
//out
$('#firsttext').hide();
});
So when a user hovers over #first, #firsttext will appear. Then, I want it so that when a user hovers over #second, #moretext should appear, etc.
I've done programming in Python, I created a sudo code and basically it is this.
text = [#firsttext, #moretext, #evenmoretext]
picture = [#first, #second, #eighth]
for number in range.len(text) //over here, basically find out how many elements are in text
$('text[number]').hide();
$('text[number], picture[number]').hover(function(){
//in
$('text[number]').show();
},function(){
//out
$('text[number]').hide();
});
The syntax is probably way off, but that's just the sudo code. Can anyone help me make the actual Javascript code for it?
try this
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink").show();
});
Why not
$('.spanlink').hide();
$('.column1of4').hover(
function() {
// in
$(this).children('.spanlink').show();
},
function() {
// out
$(this).children('.spanlink').hide();
}
);
It doesn't even need the ids.
You can do it :
$('.column1of4').click(function(){
$(this); // the current object
$(this).children('img'); // img in the current object
});
or a loop :
$('.column1of4').each(function(){
...
});
Dont use Id as $('#id') for multiple events, use a .class or an [attribute] do this.
If you're using jQuery, this is quite easy to accomplish:
$('.column1of4 .spanlink').hide();
$('.column1of4 img').mouseenter(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').show();
});
$('.column1of4 img').mouseleave(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').hide();
});
Depending on your markup structure, you could use DOM traversing functions like .filter(), .find(), .next() to get to your selected node.
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink, img").show();
});
So, the way you would do this, given your html would look like:
$('.column1of4').on('mouseenter mouseleave', 'img, .spanlink', function(ev) {
$(ev.delegateTarget).find('.spanlink').toggle(ev.type === 'mouseenter');
}).find('.spanlink').hide();
But building on what you have:
var text = ['#firsttext', '#moretext', '#evenmoretext'];
var picture = ['#first', '#second', '#third'];
This is a traditional loop using a closure (it's better to define the function outside of the loop, but I'm going to leave it there for this):
// You could also do var length = text.length and replace the "3"
for ( var i = 0; i < 3; ++i ) {
// create a closure so that i isn't incremented when the event happens.
(function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(',')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
})(i);
}
And the following is using $.each to iterate over the group.
$.each(text, function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(', ')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
});
Here's a fiddle with all three versions. Just uncomment the one you want to test and give it a go.
I moved the image inside the div and used this code, a working example:
$('.column1of4').each(function(){
$('div', $(this)).each(function(){
$(this).hover(
function(){
//in
$('img', $(this)).show();
},
function(){
//out
$('img', $(this)).hide();
});
});
});
The general idea is 1) use a selector that isn't an ID so I can iterate over several elements without worrying if future elements will be added later 2) locate the div to hide/show based on location relational to $(this) (will only work if you repeat this structure in your markup) 3) move the image tag inside the div (if you don't, then the hover gets a little spazzy because the positioned is changed when the image is shown, therefore affecting whether the cursor is inside the div or not.
EDIT
Updated fiddle for additional requirements (see comments).

How to animate an element while using .before in jquery

I want to append .item element before .content element but it just simply removes .item from previous location and append before .content.
What i want is to use some animation that slowly remove .item element from its original position and appear slowly on its new position.. how can i do this?
$Item = $('.item');
$('.content').before($Item);
Regards.
How about something like this:
$Item = $('.item');
$Item.fadeOut(1000, function() {
$('.content').before($Item);
$Item.fadeIn(1000);
}
The .fadeOut() method fades the element over the specified time (in milliseconds), and on completion calls the function which then moves the element and fades it back in.
Demo: http://jsfiddle.net/9gGAT/5/
You can also use the hide and show -methods of jquery to achieve a sliding effect. I'd also package the transition within it's own method so it can be reused, so you don't have to write the same code multiple times.
var smoothLikeSilk = function(mover, before) {
$item = $(mover);
$content = $(before);
$item.hide('slow', function() {
$content.before($item);
$item.show('slow');
});
}
$(function(){
$('#btnMove').on('click',function(){
smoothLikeSilk('.item', '.content');
});
});
http://jsfiddle.net/9gGAT/6/
Do you mean something like this:
jsFiddl Link
Try this,
$(function() {
$('#btnMove').on('click', function() {
$Item = $('.item').fadeOut('slow', function() {
$('.content').before($Item);
$Item.fadeIn('slow');
})
});
});​
Demo

Categories

Resources