Jquery. replace link if not found - javascript

I am a newbie and I have inherited some nasty jquery code. I am trying to find a way so that if an error is found then it replaces the string with another string. This is the original code..
W.load = function (b) {
var c, d, g = W.prep; S = ! 0, Q = ! 1, O = x[P], b || _(a.extend(J, a.data(O, e))), ba(l), ba(h, J.onLoad), J.h = J.height? Z(J.height, "y") - M - K: J.innerHeight && Z(J.innerHeight, "y"), J.w = J.width? Z(J.width, "x") - N - L: J.innerWidth && Z(J.innerWidth, "x"), J.mw = J.w, J.mh = J.h, J.maxWidth &&(J.mw = Z(J.maxWidth, "x") - N - L, J.mw = J.w && J.w < J.mw? J.w: J.mw), J.maxHeight &&(J.mh = Z(J.maxHeight, "y") - M - K, J.mh = J.h && J.h < J.mh? J.h: J.mh), c = J.href, V = setTimeout(function () {
B.show()
},
100), J.inline?(Y().hide().insertBefore(a(c)[0]).one(l, function () {
a(this).replaceWith(z.children())
}), g(a(c))): J.iframe? g(" "): J.html? g(J.html): $(c)?(a(Q = new Image).addClass(f + "Photo").error(function () {
//J.title = ! 1, g(Y("Error").text("This image could not be loaded"))
J.title = ! 1, a(this).href.replace('http://www.old.com','http://www.new.com');
}).load(function () {
var a; Q.onload = null, J.scalePhotos &&(d = function () {
Q.height -= Q.height * a, Q.width -= Q.width * a
},
J.mw && Q.width > J.mw &&(a =(Q.width - J.mw) / Q.width, d()), J.mh && Q.height > J.mh &&(a =(Q.height - J.mh) / Q.height, d())), J.h &&(Q.style.marginTop = Math.max(J.h - Q.height, 0) / 2 + "px"), x[1] &&(P < x.length - 1 || J.loop) &&(Q.style.cursor = "pointer", Q.onclick = function () {
W.next()
}), m &&(Q.style.msInterpolationMode = "bicubic"), setTimeout(function () {
g(Q)
},
I have changed the code to this..
J.title = ! 1, a(this).href.replace('http://www.old.com','http://www.new.com');
But its not working. Ggr! Any help would be greatly appriciated. :)
UPDATE*
The code above is the complete code for the section I am working in..
UPDATE #2
This answer works but I need to do...
a(this).attr('src', function(i, current){
if ( i === 'http://www.old.com'){
return current.replace('http://www.old.com','http://www.new.com');
}
else if ( i === 'http://www.older.com'){
return current.replace('http://www.older.com','http://www.new.com');
}
else ();
})
This isn't working!! Help!!

Try
this.href.replace('http://old.com/' , 'http://new.com/');
If you want to change the actual attribute to a new one on the current element then
this.href = this.href.replace('http://old.com/' , 'http://new.com/');
If you are inside a handler that refers to an <a> element then this refers to that object and you do not need to make a jquery object out of it, to access its properties.. so this.href will refer directly to the href property of the link.
Disclaimer: That is obfusated/encoded script and you should better find the original from which this was produced.. This code makes no sense and our suggestion are really in the blind..
From a first look it seems the this is an image and not a link, so if you want to show a new image then you would need to change the src attribute and not the href which does not exist on images..
a(this).attr('src', function(i, current){ return current.replace('http://www.old.com','http://www.new.com');})
But you should also do a console.log(a.fn.jquery) in there to make sure that a is a reference to jQuery

Do you need to do a replace ? If you just want to change the url then you can just do.
J.title = ! 1, $(this).attr('href', 'http://new.com/*');
Which will replace the current url to the new url given.

Related

Vuetify Vue - Always listening for sliding events, but only return the value once

I installed the vuetify plugin for the project in order to use a colorpicker plugin. Due to special requirements, I need to manually change the function and style of the plugin.
The plug-in has a scroll bar, each time you slide the button, it will return a current color hex value.
Now I need to make it slideable, but only return a current color value when I let go.
what should I do?
Here is how to listen to scroll events
if ('touches' in e) {
this.app.addEventListener('touchmove', this.onMouseMove, mouseMoveOptions);//滑动
Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["addOnceEventListener"])(this.app, 'touchend', this.onSliderMouseUp, mouseUpOptions);
} else {
this.app.addEventListener('mousemove', this.onMouseMove, mouseMoveOptions);
Object(_util_helpers__WEBPACK_IMPORTED_MODULE_6__["addOnceEventListener"])(this.app, 'mouseup', this.onSliderMouseUp, mouseUpOptions);
}//addEventListener is a custom function,listener event just once.
when slider moves
onMouseMove: function onMouseMove(e) {
var value = this.parseMouseMove(e).value;
this.internalValue = value;
},
parseMouseMove: function parseMouseMove(e) {
var start = this.vertical ? 'top' : 'left';
var length = this.vertical ? 'height' : 'width';
var click = this.vertical ? 'clientY' : 'clientX';
var _a = this.$refs.track.getBoundingClientRect(),
_b = start,
trackStart = _a[_b],
_c = length,
trackLength = _a[_c];
var clickOffset = 'touches' in e ? e.touches[0][click] : e[click]; // Can we get rid of any here?
// It is possible for left to be NaN, force to number
var clickPos = Math.min(Math.max((clickOffset - trackStart) / trackLength, 0), 1) || 0;
if (this.vertical) clickPos = 1 - clickPos;
if (this.$vuetify.rtl) clickPos = 1 - clickPos;
var isInsideTrack = clickOffset >= trackStart && clickOffset <= trackStart + trackLength;
var value = parseFloat(this.min) + clickPos * (this.maxValue - this.minValue);
return {
value: value,
isInsideTrack: isInsideTrack
};
},
If you are using Vue.js, I can recommend you to use Vue.js 'Event Handling', instead of addEventListener, in you <template> part, like:
<div
#mousedown="moveStartMethod($event)"
#mousemove.prevent="moveMotionMethod"
#mouseup="moveEndMethod"
>
</div>
Then in your <script> part, you can call the methods:
moveStartMethod: function (event) {
...
},
more info: https://learnvue.co/2020/01/a-vue-event-handling-cheatsheet-the-essentials/ and search for 'Handling mouse modifiers' part

jQuery "keyup" crashing page when checking 'Word Count'

I have a word counter running on a DIV and after typing in a few words, the page crashes. The browser continues to work (par scrolling) and no errors are showing in Chrome's console. Not sure where I'm going wrong...
It all started when I passed "wordCount(q);" in "keyup". I only passed it there as it would split-out "NaN" instead of a number to countdown from.
JS:
wordCount();
$('#group_3_1').click(function(){
var spliced = 200;
wordCount(spliced);
}) ;
$('#group_3_2').click(function(){
var spliced = 600;
wordCount(spliced);
}) ;
function wordCount(q) {
var content_text = $('.message1').text(),
char_count = content_text.length;
if (char_count != 0)
var word_count = q - content_text.replace(/[^\w ]/g, "").split(/\s+/).length;
$('.word_count').html(word_count + " words remaining...");
$('.message1').keyup(function() {
wordCount(q);
});
try
{
if (new Number( word_count ) < 0) {
$(".word_count").attr("id","bad");
}
else {
$(".word_count").attr("id","good");
}
} catch (error)
{
//
}
};
HTML:
<input type="checkbox" name="entry.3.group" value="1/6" class="size1" id="group_3_1">
<input type="checkbox" name="entry.3.group" value="1/4" class="size1" id="group_3_2">
<div id="entry.8.single" class="message1" style="height: 400px; overflow-y:scroll; overflow-x:hidden;" contenteditable="true"> </div>
<span class="word_count" id="good"></span>
Thanks in advanced!
This is causing an infinite loop if (new Number(word_count) < 0) {.
Your code is a mess altogether. Just study and start with more basic concepts and start over. If you want to describe your project to me in a comment, I would be glad to show you a good, clean, readable approach.
Update:
Part of having a good architecture in your code is to keep different parts of your logic separate. No part of your code should know about or use anything that isn't directly relevant to it. Notice in my word counter that anything it does it immediately relevant to its word-counter-ness. Does a word counter care about what happens with the count? Nope. It just counts and sends the result away (wherever you tell it to, via the callback function). This isn't the only approach, but I just wanted to give you an idea of how to approach things more sensefully.
Live demo here (click).
/* what am I creating? A word counter.
* How do I want to use it?
* -Call a function, passing in an element and a callback function
* -Bind the word counter to that element
* -When the word count changes, pass the new count to the callback function
*/
window.onload = function() {
var countDiv = document.getElementById('count');
wordCounter.bind(countDiv, displayCount);
//you can pass in whatever function you want. I made one called displayCount, for example
};
var wordCounter = {
current : 0,
bind : function(elem, callback) {
this.ensureEditable(elem);
this.handleIfChanged(elem, callback);
var that = this;
elem.addEventListener('keyup', function(e) {
that.handleIfChanged(elem, callback);
});
},
handleIfChanged : function(elem, callback) {
var count = this.countWords(elem);
if (count !== this.current) {
this.current = count;
callback(count);
}
},
countWords : function(elem) {
var text = elem.textContent;
var words = text.match(/(\w+\b)/g);
return (words) ? words.length : 0;
},
ensureEditable : function(elem) {
if (
elem.getAttribute('contenteditable') !== 'true' &&
elem.nodeName !== 'TEXTAREA' &&
elem.nodeName !== 'INPUT'
) {
elem.setAttribute('contenteditable', true);
}
}
};
var display = document.getElementById('display');
function displayCount(count) {
//this function is called every time the word count changes
//do whatever you want...the word counter doesn't care.
display.textContent = 'Word count is: '+count;
}
I would do probably something like this
http://jsfiddle.net/6WW7Z/2/
var wordsLimit = 50;
$('#group_3_1').click(function () {
wordsLimit = 200;
wordCount();
});
$('#group_3_2').click(function () {
wordsLimit = 600;
wordCount();
});
$('.message1').keydown(function () {
wordCount();
});
function wordCount() {
var text = $('.message1').text(),
textLength = text.length,
wordsCount = 0,
wordsRemaining = wordsLimit;
if(textLength > 0) {
wordsCount = text.replace(/[^\w ]/g, '').split(/\s+/).length;
wordsRemaining = wordsRemaining - wordsCount;
}
$('.word_count')
.html(wordsRemaining + " words remaining...")
.attr('id', (parseInt(wordsRemaining) < 0 ? 'bad' : 'good'));
};
wordCount();
It's not perfect and complete but it may show you direction how to do this. You should use change event on checkboxes to change wordsLimit if checked/unchecked. For styling valid/invalid words remaining message use classes rather than ids.
I think you should use radio in place of checkboxes because you can limit 200 or 600 only at a time.
Try this like,
wordCount();
$('input[name="entry.3.group"]').click(function () {
wordCount();
$('.word_count').html($(this).data('val') + " words remaining...");
});
$('.message1').keyup(function () {
wordCount();
});
function wordCount() {
var q = $('input[name="entry.3.group"]:checked').data('val');
var content_text = $('.message1').text(),
char_count = content_text.length;
if (char_count != 0) var word_count = q - content_text.replace(/[^\w ]/g, "").split(/\s+/).length;
$('.word_count').html(word_count + " words remaining...");
try {
if (Number(word_count) < 0) {
$(".word_count").attr("id", "bad");
} else {
$(".word_count").attr("id", "good");
}
} catch (error) {
//
}
};
Also you can add if your span has bad id then key up should return false;
See Demo

Javascript decrement -- not working in my script

var backgroundImages = new Array(); // create an array holding the links of each image
backgroundImages[0] = "style/images/bg0.png";
backgroundImages[1] = "style/images/bg1.png";
backgroundImages[2] = "style/images/bg2.png";
backgroundImages[3] = "style/images/bg3.png";
backgroundImages[4] = "style/images/bg4.png";
backgroundImages[5] = "style/images/bg5.png";
backgroundImages[6] = "style/images/bg6.png";
var ImageCnt = 0;
function nextImage(direction) // this should take into account the current value (starts at 3) and determines whether a higher or lower value should be returned based on the direction
{
if(direction == "left")
{
ImageCnt-- ;
}
if(direction == "right")
{
ImageCnt++ ;
}
document.getElementById("body-1").style.background = 'url(' + backgroundImages[ImageCnt] + ')'; //put's the new background together for rendering by using the returned value from nextImage()
if(ImageCnt == 6)
{
ImageCnt = -1;
}
}
In this script, ImageCnt ++ is working fine, on the function "nextImage('right')" but on nextImage('left') which triggers ImageCnt-- , the function breaks. What am I doing wrong? (Newbie with js)
Well, your "wrap" code says to make it -1, but what if I then go left? It will try to access -2, which doesn't exist.
Try this instead:
ImageCnt = (ImageCnt + (direction == "left" ? backgroundImages.length-1 : 1)) % backgroundImages.length;
document.getElementById("body-1").style.background = "url('"+backgroundImages[ImageCnt]+"')";
Note also that it is very inefficient to build an array piece by piece like that. Try this:
var backgroundImages = [
"style/images/bg0.png",
"style/images/bg1.png",
"style/images/bg2.png",
"style/images/bg3.png",
"style/images/bg4.png",
"style/images/bg5.png",
"style/images/bg6.png",
];

Adding a integer to a css class with jQuery

This is the code I have, now what it needs to do is increase the integer after the class name 'icon-' so that on each click the 'icon-' class gets a higher integer value ex. click -> 'icon-2', click -> 'icon-3' and so forth.
Bare in mind that the current icon shown to the user is 'icon-1'.
Also, is there a way for me to alert if it hits 'icon-10' or prevent it from trying to go further than 'icon-10' or below 'icon-1'.
$(function () {
a = 2,
b = '',
$('.icon-step-backward').click(function(){
$('#slider').removeClass();
$('#slider').addClass('icon-' - a);
});
$('.icon-step-forward').click(function(){
$('#slider').removeClass('icon-');
$('#slider').addClass('icon-' + a);
});
});
$('.icon-step-backward, .icon-step-forward').click(function () {
var s = $(this).hasClass('icon-step-backward') ? -1 : 1;
$('#slider').prop('className', function (_, p) {
return p.replace(/\d+/g, function (n) {
var j = +n + s;
return j <= 10 && j >= 1 ? j : n;
});
});
});
http://jsfiddle.net/Mwcbp/
$(function () {
var classes=["icon-1","icon-2","icon-3","icon-4","icon-5","icon-6"
,"icon-7","icon-8","icon-9","icon-10"];
var classCounter=0;
$('.icon-step-backward, .icon-step-forward').click(function () {
//caching slider object
var $slider = $('#slider'),
s = $(this).hasClass('icon-step-backward') ? -1 : 1,
tmp=counter+s,
disableButton=(s==-1)?'.icon-step-backward':'.icon-step-forward',
enableButton=(s==-1)?'.icon-step-forward':'.icon-step-backward';
$(enableButton).show();
if(tmp<classes.length && tmp>0){
$slider.removeClass(classes[counter]);
counter=counter+s;
$slider.addClass(classes[counter]);
}else{
$(disableButton).hide();
}
});
});
If you have multiple .icon-step buttons having to manipulate multiple slider (#slider suggest otherwise) than you can add the classCounter as $("#slider").data to be used specifically for this slider.

Trouble with onclick attribute for img when used in combination with setInterval

I am trying to make images that move around the screen that do something when they are clicked. I am using setInterval to call a function to move the images. Each image has the onclick attribute set. The problem is that the clicks are not registering.
If I take out the setInterval and just keep the images still, then the clicks do register.
My code is here (html, css, JavaScript): https://jsfiddle.net/contini/nLc404x7/4/
The JavaScript is copied here:
var smiley_screen_params = {
smiley_size : 100, // needs to agree with width/height from css file
num_smilies: 20
}
var smiley = {
top_position : 0,
left_position : 0,
jump_speed : 2,
h_direction : 1,
v_direction : 1,
intvl_speed : 10, // advance smiley every x milliseconds
id : "smiley"
}
function randomise_direction(s) {
var hd = parseInt(Math.random()*2);
var vd = parseInt(Math.random()*2);
if (hd === 0)
s.h_direction = -1;
if (vd === 0)
s.v_direction = -1;
}
function plotSmiley(sp /* sp = smiley params */) {
var existing_smiley = document.getElementById(sp.id);
if (existing_smiley !== null)
// delete existing smiley so we can move it
document.getElementById("smileybox").removeChild(existing_smiley);
var smiley_to_plot = document.createElement('img');
smiley_to_plot.setAttribute('src', "http://i.imgur.com/C0BiXJx.png");
smiley_to_plot.setAttribute('id', sp.id);
smiley_to_plot.setAttribute('onclick', "my_click_count()");
smiley_to_plot.style.position = 'absolute';
smiley_to_plot.style.top = sp.top_position + "px";
smiley_to_plot.style.left = sp.left_position + "px";
document.getElementById("smileybox").appendChild(smiley_to_plot);
}
function random_direction_change() {
var r = parseInt(Math.random()*200);
if (r===0)
return true;
else
return false;
}
function moveFace(sp_array /* sp_array = smiley params array */) {
var i;
var sp;
for (i=0; i < sp_array.length; ++i) {
// move ith element
sp = sp_array[i];
if (
(sp.h_direction > 0 && sp.left_position >= smiley_screen_params.width - smiley_screen_params.smiley_size) ||
(sp.h_direction < 0 && sp.left_position <= 0) ||
(random_direction_change())
) {
sp.h_direction = -sp.h_direction; // hit left/right, bounce off (or random direction change)
}
if (
(sp.v_direction > 0 && sp.top_position >= smiley_screen_params.height - smiley_screen_params.smiley_size) ||
(sp.v_direction < 0 && sp.top_position <= 0) ||
(random_direction_change())
) {
sp.v_direction = -sp.v_direction; // hit top/bottom, bounce off (or random direction change)
}
sp.top_position += sp.v_direction * sp.jump_speed;
sp.left_position += sp.h_direction * sp.jump_speed;
plotSmiley(sp);
}
}
if (typeof Object.create !== 'function') {
Object.create = function(o) {
var F = function () {};
F.prototype = o;
return new F();
};
}
function generateFaces() {
var smilies = new Array();
var s;
var i;
var css_smileybox=document.getElementById("smileybox");
var sb_style = getComputedStyle(css_smileybox, null);
// add info to the screen params
smiley_screen_params.width = parseInt(sb_style.width);
smiley_screen_params.height = parseInt(sb_style.height);
// create the smileys
for (i=0; i < smiley_screen_params.num_smilies; ++i) {
s = Object.create(smiley);
s.id = "smiley" + i;
s.top_position = parseInt(Math.random() * (smiley_screen_params.height - smiley_screen_params.smiley_size)),
s.left_position = parseInt(Math.random() * (smiley_screen_params.width - smiley_screen_params.smiley_size)),
randomise_direction(s);
smilies.push(s);
}
setInterval( function(){ moveFace(smilies) }, smiley.intvl_speed );
}
var click_count=0;
function my_click_count() {
++click_count;
document.getElementById("mg").innerHTML = "Number of clicks: " + click_count;
}
generateFaces();
The generateFaces() will generate parameters (for example, coordinates of where they are placed) for a bunch of smiley face images. The setInterval is within this function, and calls the moveFace function to make the smiley faces move at a fixed interval of time. moveFace computes the new coordinates of each smiley face image and then calls plotSmiley to plot each one on the screen in its new location (removing it from the old location). The plotSmiley sets the onclick attribute of each image to call a dummy function just to see if the clicks are registering.
Thanks in advance.
This is not a complete answer but it could give you some perspective to improve your code.
First of all, your idea of deleting the existing img so wrong. If it does exist, all you need is to just change its position so instead of this
if (existing_smiley !== null)
// delete existing smiley so we can move it
document.getElementById("smileybox").removeChild(existing_smiley);
you should do something like this:
if (existing_smiley !== null)
var smiley_to_plot = existing_smiley;
else {
var smiley_to_plot = document.createElement('img');
smiley_to_plot.setAttribute('src', "http://i.imgur.com/C0BiXJx.png");
smiley_to_plot.setAttribute('id', sp.id);
smiley_to_plot.style.position = 'absolute';
document.getElementById("smileybox").appendChild(smiley_to_plot);
smiley_to_plot.addEventListener('click', my_click_count);
}
smiley_to_plot.style.top = sp.top_position + "px";
smiley_to_plot.style.left = sp.left_position + "px";
As you can see new image is only being added if it's not already there. Also notice that adding events by using .setAttribute('onclick', "my_click_count()"); is not a good way to do. You should use .addEventListener('click', my_click_count); like I did.
Like I said this is not a complete answer but at least this way they response to the click events now.
FIDDLE UPDATE
Good luck!

Categories