Issue: Cannot change attributes src and alt independently for multiple images. Any change made, affects all the other images that have previously had a change made.
Question: How can I optimize following JS/Jquery to allow attribute changes for multiple images?
See full code here: JS Fiddle
$(function () {
$("#editImage").hide();
$("img").click(function () {
var imgChange = this;
$('#imageAlt').val($(imgChange).attr('alt'));
$('#imageSrc').val($(imgChange).attr('src'));
$("#editImage").css({
top: $(this).offset().top - $('#editImage').height() - 5,
left: $(this).offset().left
}).show();
$("#imageEditDone").click(function () {
var imgSrc = $("#imageSrc").val();
var imgAlt = $("#imageAlt").val();
$(imgChange).attr('src', imgSrc).attr('alt', imgAlt);
});
});
});
$("#imageEditDone").click(function () {
$("#editImage").hide();
});
You're binding a click handler within another click handler repeatedly which is a no-no. Also, you need to change the scope of your imgChange variable. Try:
var imgChange;
$(function () {
$("#editImage").hide();
$("img").click(function () {
imgChange = this;
$('#imageAlt').val($(imgChange).attr('alt'));
$('#imageSrc').val($(imgChange).attr('src'));
$("#editImage").css({
top: $(this).offset().top - $('#editImage').height() - 5,
left: $(this).offset().left
}).show();
$("#imageSrc").text(imgChange.attr('alt', this));
});
});
$("#imageEditDone").click(function () {
$("#editImage").hide();
var imgSrc = $("#imageSrc").val();
var imgAlt = $("#imageAlt").val();
$(imgChange).attr('src', imgSrc).attr('alt', imgAlt);
});
jsFiddle example
I'm just not sure what you're trying to do with the line $("#imageSrc").text(imgChange.attr('alt', this));, although it doesn't affect the answer.
Related
I want to use a read more button after a text is larger than 300 characters.
I use this jQuery to fix this, but it is not working as I want.
var $j = jQuery.noConflict();
$j('.reviewtekst').each(function() {
var $pTag = $j(this).find('p');
if($pTag.text().length > 300){
var shortText = $pTag.text();
shortText = shortText.substring(0, 300);
$pTag.addClass('fullArticle').hide();
$pTag.append('<a class="read-less-link">Lees minder</a>');
$j(this).append('<p class="preview">'+shortText+'</p><div class="curtain-shadow"></div><a class="read-more-link">Read more</a>');
}
});
$j(document).on('click', '.read-more-link', function () {
$j(this).parent().hide().prev().show();
});
$j(document).on('click', '.read-less-link', function () {
$j(this).parent().hide().next().show();
});
See this JSFiddle: https://jsfiddle.net/8cm67cun/1/
How can I make this work, to display the <a> class outside the <p> class.
Here is updated version https://jsfiddle.net/8cm67cun/2/ now it works fine with a tag outside the p
$j(document).on('click', '.read-more-link', function () {
$j(this).hide().parent().find('.preview').hide().prev().show();
});
$j(document).on('click', '.read-less-link', function () {
$j(this).parent().hide().next().show();
$j(this).parents('.reviewtekst').find('.read-more-link').show();
});
I want to hide a div once my slider passes a scrollTop() value of 200px. I've looked at this article and tried using it as a template for what I want. I have the following code, but its not hiding the element. Live site
function removeArrow() {
$(window).scroll(function() {
if($('.portfolio-sliders:first-child').scrollTop() > 100) { //use `this`, not `document`
$('.scrl-dwn').css({
'display': 'none'
});
}
});
}
UPDATE
I've updated by code:
function removeArrow() {
$(window).scroll(function() {
var slider = $('.portfolio-sliders:first-child').position.top;
if(slider >= 10) {
$('.scrl-dwn').hide();
}
});
}
which should work, but its not...
Position is a function, not a property. You need to call the function with ():
var slider = $('.portfolio-sliders:first-child').position().top;
Replace your whole removeArrow function with this code.
(If you open your live site, and run this in the console, you can see it's working).
The scroll event never fired, so I handled theese mousewheel events instead.
$(window).bind('DOMMouseScroll mousewheel', function() {
var div = $(".portfolio-sliders:first-child"),
top = div.position().top,
display = top < 400 ? 'none' : '';
$('.scrl-dwn').css({ 'display': display });
});
Use This :
$(window).scroll(function(){
if ($(window).scrollTop() > 660)
{
$(".Left-Section").css("position", "fixed");
$(".Center-Content").css("margin-top", "0");
$(".Right-Nav img").css("transform", "rotate(360deg)");
}
;)
After declaring height() variables for multiple loaded elements which have different variables for each, the animate() function doesn't seem to be loading the variable excHeight.
What would be the best way to use the value of excHeight for the animate() as below?
$(".exPand a").click(function (event) {
event.preventDefault();
var post_id = $(this).attr("rel");
var postHeight = $(this).closest('.boxy')
.find('.articleImageThumb')
.height();
var excHeight = $(this).closest('boxy')
.find('.articleImageThumb')
.find('.initialPostLoad')
.height();
$.ajaxSetup({cache:false});
$(this).closest('.boxy')
.animate({height: postHeight+excHeight}, 1000);
$(this).closest('.boxy')
.find('.articleImageThumb')
.animate({top: 0}, 1000);
$(this).closest('.boxy').find('.articleTitle')
.animate({bottom: excHeight}, 1000);
$(this).closest('.boxy').find('.postmetadata')
.animate({bottom: excHeight}, 1000);
});
Seems like it is not working because you forgot "dot" in boxy class name: var excHeight = $(this).closest('boxy') , must be like this: var excHeight = $(this).closest('.boxy')
I have this function:
$('body').on('click', '.kategorija_izbor ul a, .mali_oglas a[role=pretraga]', function(e){
var mgl_wrapper = $('.mali_oglasi_wrapper'),
mgl = $(".mali_oglasi"),
mgl_space = $(this).attr('href').replace(/\s+/g, '-').toLowerCase();
link = mgl_space + ' .mali_oglasi';
mgl.animate({'opacity' : 0}, 400, function(){
mgl_wrapper.load(link, function(){
mgl.animate({'opacity' : 1}, 400);
});
});
e.preventDefault();
});
It is working, but I would like to know is there another way to do it. It seems to me that this way is time consuming and resource inefficient. Every time page is clicked script is going through DOM and search for specific elements. Is there a way to store .kategorija_izbor ul a and .mali_oglas a[role=pretraga] (they are bout loaded via load function )?
EDIT I
.kategorija_izbor ul a and .mali_oglas a[role=pretraga] are children of mgl_wrapper *( $('.mali_oglasi_wrapper')), and they are dynamically created every time they are clicked.
If the elements are only being loaded into mgl, just restrict the click handler's scope so jQuery doesn't have to search through the entire body:
var $mgl_wrapper = $('.mali_oglasi_wrapper');
var $mgl = $('.mali_oglasi');
$mgl.on('click', '.kategorija_izbor ul a, .mali_oglas a[role=pretraga]', function(e) {
var mgl_space = this.href.replace(/\s+/g, '-').toLowerCase();
$mgl.animate({'opacity' : 0}, 400, function() {
$mgl_wrapper.load(mgl_space + ' .mali_oglasi', function() {
$mgl.animate({'opacity' : 1}, 400);
});
});
e.preventDefault();
});
I'm having some trouble with my Javascript when using jQuery UI's sortable method on dynamically created elements. When I hover an image it displays a larger version of the image which follows the cursor within the thumbnail. Then, when I'm sorting/dragging an image it displays the larger image with it's position set to far away from the thumbnail. The larger image should be hidden when sorting :-)
I've made a screenr so it's easier for you to see what I mean: http://screenr.com/jjv8
My code for hooking up the events:
// Selected photos hover
$('ul li img').live('mouseenter', function () {
var img = $(this);
var imgDiv = $(this).parent().find('.hover-image');
img.mousemove(function (e) {
imgDiv.show();
var x = e.pageX;
var y = e.pageY - 50;
imgDiv.css({ "top": y + "px", "left": x + "px" });
});
});
$('ul li img').live('mouseleave', function () {
$(this).parent().find('.hover-image').fadeOut('fast');
});
And my code for sorting:
selectedPhotosList.sortable({
handle: '.selected-thumbnail-image',
start: function (event, ui) {
ui.item.find('.selected-thumbnail-image').die('mouseenter');
ui.item.find('.hover-image').hide();
}
});
Yes, I'm using .live() since this is a datatype which resides in Umbraco CMS which uses an older version of jQuery, so .on() doesn't work :-)
Anyone got a hint on how to get this to work?
EDIT
I found the bug:
In my .live('mouseenter', function()... I'm calling imgDiv.show(); every time the cursor moves.
Doing it like this works:
// Selected photos hover
$('ul li img').live('mouseenter', function () {
var img = $(this);
var imgDiv = $(this).parent().find('.hover-image');
imgDiv.show();
img.mousemove(function (e) {
var x = e.pageX;
var y = e.pageY - 50;
imgDiv.css({ "top": y + "px", "left": x + "px" });
});
});
$('ul li img').live('mouseleave', function () {
$(this).parent().find('.hover-image').fadeOut('fast');
});
However, this creates another bug when using IE.: Screenr: http://screenr.com/1Iv8
The hover image is shown once before actually triggering the mousemove function :-/ Any way to overrule this?
I'd suggest:
$('ul li img').off('mouseenter');
.die() should work for you. Read the documentation on it
$('ul li img').die('mouseenter');
Something like that should work.
Found a solution to this which works in IE7+, Chrome and Firefox, although it's a bit ugly (not sure if that is an understatement ;-)):
In the sortable start event I create a copy of the hover-image and store it in a variable then removing it from the DOM. Then in the stop event I prepend it to the listitem that has been dragged/sorted. Code:
var tempHoverImage = "";
selectedPhotosList.sortable({
handle: '.selected-thumbnail-image',
start: function (event, ui) {
var hoverImage = ui.item.find('.hover-image');
tempHoverImage = hoverImage;
hoverImage.remove();
},
stop: function (event, ui) {
ui.item.prepend(tempHoverImage);
}
});