Each, attr, or this? - javascript

I'm not sure if I need the each() function here or if I can somehow do this with this. I'm trying to switch the src attribute based on the if statement. It works except that it switches them both to hifi1.jpg. How do I make it so it applies each img's data-websrc value to itself?
HTML:
<img class="airsrc" src="lofi1.jpg" data-websrc="hifi1.jpg" alt="example1">
<img class="airsrc" src="lofi2.jpg" data-websrc="hifi2.jpg" alt="example2">
JS:
jQuery(document).ready(function($) {
var airsrc = $('.airsrc');
airsrc.each(function() {
if ( Modernizr.mq('(min-width:480px)') ) {
var src = $(this).data('websrc');
airsrc.attr('src', src);
}
});
});
Update: Solution:
jQuery(document).ready(function($) {
if ( Modernizr.mq('(min-width:480px)') ) {
$('.airsrc').each(function() {
var $this = $(this);
var src = $this.data('websrc');
if ( src != '' ) {
$this.attr('src', src);
}
});
}
});
That works in browsers that support custom data attributes, which from my testing I've found to mean FF/Chrome/Opera/Safari. Maybe IE9. I think getAttribute can be used though for (older) IE.

var $this = $(this),
src = $this.data('websrc');
$this.attr('src', src);
It was applying to both, because you were applying it to the whole jQuery object airsrc.
You had to specifically reference the current element with $(this)
or...
Do it like the above code, which assigns $(this) to $this in order to cache it, for avoiding further lookups. Then you get its data and change its attribute.

You'll want to use this inside the each to get the specific item for that iteration, wrapped in jQuery, of course. With some small optimizations...
jQuery(document).ready(function($) {
if (Modernizer.mq('(min-width:480px)')) {
$('.airsrc').each(function() {
var $this = $(this),
src = $(this).data('websrc');
$this.attr('src', src);
});
}
});
Note that if you check the condition outside the each, you only have to do it once. Also, you can avoid reconstituting the jQuery of this by assigning it to a variable then reusing it.

airsrc.attr('src', src); should be $(this).attr('src', src); and everything will be wonderful

You can make your code a lot shorter by using a feature of the attr method:
jQuery(function($) {
if ( Modernizr.mq('(min-width:480px)') ) {
$('.airsrc').attr('src', function() {
return $(this).data('websrc');
});
}
});

Related

Remove resize at the end of img src

I am trying to remove a string at the end of my img src for all my img elements on the page.
An example of an img src as it appears now
http://www.example.com/B-UV-image-copy.jpg?resize=320%2C180
How I want it to be
http://www.example.com/B-UV-image-copy.jpg
I am trying to use javascript in the footer to find all img elements then remove ?resize=320%2C180 from all of them. The string "?resize=320%2C180" is always the same on all the images I want to effect.
Currently my code looks like this:
<script>
$('img').attr('src', function(index, attr) {
return attr.replace("?resize=320%2C180", "");
});
</script>
I appreciate I may be going about this all wrong. Currently the above script does nothing but I get an error in firebug:
Uncaught TypeError: undefined is not a function
Any help would be appriciated.
Your code works. You just need the DOM to be loaded and you need to make sure $ is tied to jQuery.
<script>
(function ($) {
$(document).ready(function() {
$('img').attr('src', function(index, attr) {
return attr.replace("?resize=320%2C180", "");
});
});
}(window.jQuery));
</script>
Works for me. You just need to ensure that the DOM is ready before you ask jQuery it to manipulate it:
$(function(){
$('img').attr('src', function(index, attr) {
return attr.replace("?resize=320%2C180", "");
});
});
http://jsfiddle.net/os5rhw23/
Using RegExp to strip off all the query part from a URL:
jQuery(function ($) {
$('img').attr('src', function(index, attr) {
return attr.replace(/\?.*$/i, '');
});
});
The other two answers are correct, but the nicest shorthand for a DOM ready handler and a locally scoped $ for jQuery is jQuery(function ($) { your code here}:
e.g.
<script>
jQuery(function ($) {
$('img').attr('src', function(index, attr) {
return attr.replace("?resize=320%2C180", "");
});
});
</script>
If you want to do this with pure JS, inline in the footer without the need for jQuery you can simply loop through all images - so long as this script in on the page at some point after the images (eg just before the close body)
<body>
<!-- some html, blah blah -->
<script>
var images = document.images,
i = images.length;
while(i--) {
var image = images[i];
image.src = image.src.replace("?resize=320%2C180", "");
}
<script>
</body>
http://jsfiddle.net/os5rhw23/1/

jQuery Plugin - How to add / bind events

Ok this is my first stab at creating a jQuery plugin so I am going off tutorials currently.
This far I have
(function($)
{
$.tippedOff = function(selector, settings)
{
var config = {
'top':0,
'left':0,
'wait':3000
};
if(settings){$.extend(config, settings);}
var $elem = $(selector);
if($elem.length > 0)
{
$elem.each(function()
{
$(this).css({"color":"#F00"});
})
}
return this;
};
})(jQuery);
Which works for changing the text color of the provided elements. However. I want to add functionality to elements that the plugin takes effect on. Such as a hover or click event. But I can't wrap my head around that idea at the moment, seeing as the selector can be anything. So its not like I can hardcode something in per say thats specific like I would through normal jQuery methods.
So, with that, how do I go about adding that type of functionality to things after its been rendered?
When creating plugins, it is very easy to over-complicate things, so try to keep things nice and simple.
I have provided you with TWO examples of the tippedOff plugin. Here is also a jsfiddle demo of both plugins.
The first uses your original code as is (NO SIGNIFICANT CHANGES MADE):
$.tippedOff = function(selector, settings)
{
var config = {
'top':0,
'left':0,
'wait':3000
};
if(settings){$.extend(config, settings);}
var $elem = $(selector);
if($elem.length > 0)
{
$elem.each(function()
{
//bind mouseenter, mouseleave, click event
$(this).css({"color":"#F00"})
.mouseenter(function(){
$(this).css({"color":"green"});
})
.mouseleave(function(){
$(this).css({"color":"#F00"});
})
.click(function(){
$(this).html('clicked');
});
})
}
return this;
};
This one, however, is based on your original code. Basically, I have reconstructed your original code using these tips. This is how I would personally go about it. I have also provided you with a breakdown below of changes made. (SIGNIFICANT CHANGES MADE):
$.fn.tippedOff = function(settings) {
var config = $.extend( {
'top':0,
'left':0,
'wait':3000,
'color': 'orange',
'hoverColor': 'blue'
}, settings);
return this.each(function() {
$this = $(this);
$this.css({ 'color': config.color})
.mouseenter(function(){
$this.css({ 'color': config.hoverColor });
})
.mouseleave(function(){
$this.css({ 'color': config.color });
})
.click(function(){
$this.html('clicked');
});
});
}
----------------------------------------
Breakdown:
Original Code:
$.tippedOff = function(selector, settings) {
Changed:
$.fn.tippedOff = function( settings ) {
Comments:
The difference between $.tippedOff and $.fn.tippedOff is huge! Adding your plugin to the $.fn namespace rather than the $ namespace will prevent you from having to provide a selector and makes life simplier.
I personally like this answer, in which #Chad states:
My rule of thumb I follow is: use $. when it is not DOM related (like ajax), and use $.fn. when it operates on elements grabbed with a selector (like DOM/XML elements).
Original Code:
if(settings){$.extend(config, settings);}
Changed:
var config = $.extend( {
'top':0,
'left':0,
'wait':3000
}, settings);
Comments:
Having an if statement is redundant. .extend() does all the work for you.
Original Code:
var $elem = $(selector);
if($elem.length > 0)
{
$elem.each(function()
{
$(this).css({"color":"#F00"});
})
}
return this;
Changed:
return this.each(function() {
$this = $(this);
$this.css({ 'color': config.color});
});
Comments:
Using return this.each(function(){}) is good practice and maintains chainability. Not only that, you will no longer need to worry about the selector's length.
*NOTE: If you want to add additional events, then use different methods within your plugin: jQuery Doc Reference - Authoring Plugins.
I hope this helps and please let me know if you have any questions!
I have not enough reputation points to comment and fully agree with Dom, who is very knowledgeable. I only would like to add that within the changed code it would be better to create a local variable by using the var keyword:
var $this = $(this);
This will make the plugin better and allows you to apply the plugin to multiple elements one the page as for example:
$('#testX').tippedOff2();
$('#testY').tippedOff2();
$('#testZ').tippedOff2();

Unexpected jQuery syntax error by chaining a plug-in after .find()

I've baked a plug-in to handle runtime searches on input fields I'm using all over a big site.The plug-in works perfect in every situation but this http://jsfiddle.net/tonino/v8d2A/
$(document).ready(function () {
var callback_methods = { /* methods here */ };
var input_html = '<div class="search"><input name="search-field" value="Search..."></div>';
$(document).on('click', 'div.add', function (event) {
if (!$('li div.add + div').hasClass('search')) {
var input = $(this).after(input_html).parent().find('input');
input.focus();
input.hunter({url:'<?php echo $this->request->base; ?>/searches', callback:callback_methods, var_name:'data[Search][term]'});
// other code after
}
});
});​
If I comment the hunter plug-in everything works fine.
I'm sure is some concept on how it must be structured, here is the code: jquery.hunter.1.3.js
Why my plug-in make this error in this situation, where I'm wrong on writing it?
the problem is this part of your code:
var selector = this.selector;
var def_css = {backgroundPosition:'-16px center', paddingLeft:$(selector).css('padding-left')}
if (settings.loader) { setStyle(def_css); }
var selector = this.selector;
and later:
$(this.selector).blur(function () {
first of all your code wont work when the if-condition is fulfilled, because you are trying to redeclare the variable 'selector' inside the if block. just leave the var-statement out there:
if (settings.loader) { setStyle(def_css); }
selector = this.selector;
but YOUR MAIN-problem is that 'this.selector' contains '.parent() input' which i doubt is a valid jQuery selector.
why are you doing that? why dont you just use $(this) save it into a variable and use this???
eg:
// first line in your plugin
$this = $(this)
// later you could use the $this var
$this.blur(function () {
To get rid of the error change this line:
var input = $(this).after(input_html).parent().find('input');
To the following:
var input = $(input_html).insertAfter($(this));
The core problem though is that the jquery.hunter plugin is using the this.selector variable for some reason - you don't need this - the plugin should use $(this) instead of $(this.selector)

On Click Change another elements source

Working version of broken code here http://jsfiddle.net/Uey6W/8/
Having trouble figuring out how to change an attribute on another element form a click function
sniping
$('#black').click(function() {
$('#blackbox').slideToggle('slow', function() {});
$('#yellowbox').slideUp();
});
here on the click im hoping to not just hide the other element but also revert the other button
Basically how can i toggle another button to its closed state when another button switches to being open
$("#black").toggle(
function () {
var src = $(this).attr("src").replace("ready.png", "pressed.png");
$(this).attr("src", src);
},
function () {
var src = $(this).attr("src").replace("pressed.png", "ready.png");
$(this).attr("src", src);
}
);
$('#black').click(function() {
$('#blackbox').slideToggle('slow', function() {});
$('#yellowbox').slideUp();
});
$("#yellow").toggle(
function () {
var src = $(this).attr("src").replace("ready.png", "pressed.png");
$(this).attr("src", src);
},
function () {
var src = $(this).attr("src").replace("pressed.png", "ready.png");
$(this).attr("src", src);
}
);
$('#yellow').click(function() {
$('#yellowbox').slideToggle('slow', function() {});
$('#blackbox').slideUp();
});
From what I can see in the api reference, toggle doesn't take two functions as parameters. And you're passing an empty function to slideToggle (just omit the empty function as a parameter if that's the intention). It looks like you're on the right train of thought with just a few errors.
Edit: Was looking at the wrong toggle. Correct documentation here.
Answer was right in my face the whole time inorder to revert the other buttons i just alter the click statement
$('#black').click(function() {
$('#blackbox').slideToggle('slow', function() {});
$('#yellowbox').slideUp();
$('yellow').atr('src', ready.png)
});
You could pretty much achieve the exact same thing by doing :
var btn1 = "ready.png",
btn2 = "pressed.png";
$("#black, #yellow").on('click', function() {
$("#black, #yellow").not(this).prop('src', this.src);
this.src = this.src==btn1 ? btn2 : btn1;
$('#'+this.id+'box').slideToggle('slow').siblings('div').slideUp('slow');
});
FIDDLE

Link detect and replace the other,in js

Hello
I wonder how Replace automatically links on my site
that start with:
http://site.com/00000/
to:
http://site.com/11111/
detects> replaces
CSS3 attribute "starts with" selectors help you there (and jQuery supports them on all of the browsers it supports — with native features if possible, for speed). Then just use an each loop and update the href property of the raw a element:
$("a[href^='http://site.com/00000/']").each(function() {
this.href = "http://site.com/11111/" + this.href.substring(21);
});
You can use jQuerys .attr() method. You don't need to explicitly invoke .each(), jQuery will take care of you if your selector hits multiple nodes. Since version 1.4.1, .attr() like many other setters, takes a function as argument. This function gets the index and the actual value passed in. Whatever you return from this callback is going to be the new value.
$(document).ready(function () {
$('a').attr('href', function(_, href) {
return href.replace('246619', '262257');
});
});
Demo: http://www.jsfiddle.net/qR2NU/
Reference: .attr()
<script type="text/javascript">
$(document).ready(function () {
var urlContain = new RegExp('Detect Value Here');
$('a').each(function () {
var href = this.getAttribute('href').replace(urlContain, 'Replacement here');
$(this).attr('href', href);
});
});
</script>
This code loops through every link on the page that has a href attribute once the DOM has loaded and performs the required replace:
$(function() {
$('a').each(function() {
var href = $(this).attr('href');
if (href !== undefined) {
href = href.replace(/246619/g, '262257');
}
$(this).attr('href', href);
});
});
The above relies on jQuery but judging by the tags you used for your question, you are already using it.
Untested:
$("a[href^=http://site.com/00000/]").each(function() {
this.href = "http://site.com/11111/" + this.href.substr("http://site.com/00000/".length");
});

Categories

Resources