How can I tell, in JavaScript/jQuery if a link is Javascript?
For example:
Trigger
Trying to make sure a script only logs links, and not javascript, anchors, etc.
Basically I need to capture the href of the link as I .each through them (already done) I just need a reliable way to check that variable to see if it is javascript, ie, function w/e
var rand = function() {
return Math.random().toString(36).substr(2);
};
$(function(){
$('#lhcb a').each(function() {
var rawlink = $(this).attr("href");
var link = encodeURIComponent( rawlink );
var token = rand();
var href = $(this).prop('href');
var proceed = $.get( "lhc/link.php?link=" + link + "&a=c", function( data ) {
if ( data == 1 ) {
return true;
} else {
return false;
}
});
if ( href.match("^javascript:") ) {
proceed = false;
}
if ( rawlink.charAt(0) != '#' ) {
if ( proceed ) {
$(this).after( " <span style='font-size:xx-small;'>( Hits: <span id='" + token + "'></span> )</span>" );
$.get( "lhc/link.php?link=" + link + "&a=q", function( data ) {
$('#' + token).html(data);
});
$(this).attr( "href", "lhc/link.php?link=" + link + "&a=g" );
}
}
});
});
This is what I have, but as mentioned below, it wouldn't be able to see if the href is just a function without the JavaScript declaration.
A little script can help. I wrote a sample:
http://jsfiddle.net/qXkHX/
var normalLinks = [];
$("a").each(function(i) {
var a = $(this);
var href = $.trim(a.attr("href"));
if(href.indexOf("javascript:") !== 0) normalLinks.push(href);
});
$("#result").text(normalLinks.join(","));
It iterates through the anchors in the document and pushes every link that does not start with javascript:. Maybe this helps.
Related
Disclaimer: I know my code is pretty bad. I'm not very experienced with JavaScript yet.
So I built a gallery with filtering using JavaScript and the WP Rest API. I finally have it working, but after a few clicks between the gallery sub-categories, the page starts slowing down and eventually crashes. I imagine I'm doing something really inefficient that is killing the page, but I'm not sure what the main culprit is.
Besides the other obvious issues with how I've written the code, what might be causing it and is there a good way to test performance issues like this?
(Here's a link to a working version of this: http://victorysurfaces.x10host.com/gallery/)
Edit: Updated code with fix for extra HTML DOM nodes being added by lightbox code. Didn't fix page crashing issue, unfortunately.
Update: I've noticed that sometimes when I click on a sub-category, it makes more network requests, but sometimes it doesn't. I feel like this might be important.
Update 2: I think it might have something to do with the event listeners I'm adding. Since I'm adding the sub-categories dynamically, I have to add the event listeners after they have been loaded, but the event listeners from the previous run seem to remain, so the number of event listeners just grows and grows. I don't know what to do about that.
<div class="gallery">
<div class="medium-wrapper">
<div class="gallery__filters text-center">
<div class="gallery__main-filters">
<button class="category-filter main-category active" data-category="residential">Residential</button>
<span>|</span>
<button class="category-filter main-category" data-category="commercial">Commercial</button>
</div>
<div class="gallery__category-filters"></div>
</div>
<div class="gallery__images"></div>
</div>
</div>
<script>
/* I'm so sorry for this monstrosity. This was way more complicated than I thought and in the end I just wanted it to work */
jQuery(document).ready(function($) {
$('.main-category').on('click', function() {
$('.main-category').removeClass('active');
$(this).addClass('active');
});
initLightbox();
});
jQuery( function( $ ) {
$.getJSON("/wp-json/wp/v2/gallery-categories", function( data ) {
var currentMainCategory = $('.main-category.active').data('category');
getSubCategories();
var currentSubCategory = '';
document.querySelectorAll('.main-category').forEach( function(trigger) {
trigger.addEventListener('click', function() {
resetCategories($(this).data('category')); }, false);
});
function getSubCategories() {
var categoriesArray = [];
var subCategories = data.map(function(category) {
if( category.acf.gallery_section.trim().toLowerCase() === currentMainCategory) {
var setCategory = "<button class='category-filter sub-category' data-category='" + category.acf.category_title + "'>" + category.acf.category_title + "</button>";
categoriesArray.push(setCategory);
}
});
$('.gallery__category-filters').html(categoriesArray);
getPhotos();
}
function resetCategories(mainCategoryTitle) {
currentMainCategory = '';
currentSubCategory = '';
$('.sub-category').removeClass('active');
$('.gallery__category-filters').empty();
currentMainCategory = mainCategoryTitle;
getSubCategories();
}
function setSubCategory() {
currentSubCategory = document.querySelector('.sub-category.active').dataset.category;
getPhotos();
}
var galleryPhotos;
function getPhotos(photos) {
$('.gallery__images').empty();
var mainCategory = currentMainCategory.trim().toLowerCase();
if( (currentSubCategory !== undefined) && (currentSubCategory !== '' ) ) {
var subCategory = currentSubCategory.trim().toLowerCase();
}
galleryPhotos = data.map(function(category) {
if( category.acf.gallery_section.toLowerCase() === mainCategory ) {
if( subCategory !== '' && subCategory !== undefined) {
var categoryTitle = category.acf.category_title.toLowerCase().trim();
if( categoryTitle === subCategory ) {
var galleryCategory = category.acf.gallery_items;
var categoryPhotos = galleryCategory.map(function(photo) {
var galleryPhoto = "<div class='gallery__item'><a class='lightbox-link' href=''><img class='full-width lightbox-target' src='" + photo.gallery_item_image.sizes.flexible + "' alt='" + photo.gallery_item_image.alt + "'></a></div>";
return galleryPhoto;
});
$('.gallery__images').append(categoryPhotos);
}
} else {
var galleryCategory = category.acf.gallery_items;
var categoryPhotos = galleryCategory.map(function(photo) {
var galleryPhoto = "<div class='gallery__item'><a class='lightbox-link' href=''><img class='full-width lightbox-target' src='" + photo.gallery_item_image.sizes.flexible + "' alt='" + photo.gallery_item_image.alt + "'></a></div>";
return galleryPhoto;
});
$('.gallery__images').append(categoryPhotos);
}
}
});
$('.sub-category').on('click', function() {
$('.sub-category').removeClass('active');
$(this).addClass('active');
setSubCategory();
});
checkOrientation();
handleLightboxUpdate();
}
});
});
function checkOrientation() {
document.querySelectorAll('.lightbox-target').forEach(function(item) {
var image = new Image();
image.src = item.src;
image.onload = function() {
if(image.naturalHeight >= image.naturalWidth) {
item.classList.add('portrait');
}
}
});
}
function initLightbox() {
var $overlay = jQuery('<div id="overlay"></div>');
var $container = jQuery('<div class="lightbox">×</div>');
var $image;
var $imageClone;
jQuery('body').append($overlay);
$overlay.click(function(){
$overlay.hide();
});
$overlay.append($container);
}
function handleLightboxUpdate() {
document.querySelectorAll('.lightbox-link').forEach( function(trigger) {
trigger.addEventListener('click', function() {
event.preventDefault();
jQuery('.lightbox-image').remove();
$image = jQuery(this).find('.lightbox-target');
$imageClone = $image.clone();
if($imageClone.hasClass('portrait')) {
$imageClone.addClass('resize-lightbox');
}
jQuery('#overlay').show();
//add image to overlay
$imageClone.addClass('lightbox-image').appendTo('#overlay .lightbox');
});
});
}
</script>
I'm not looking much into code, but I can tell you what's going on here. Page slows down with each 'subcategory' click, because you add more and more HTML nodes into the page until it's just too much. To be specific you add <div id="overlay">...</div> exponentially with every click.
is there a good way to test performance issues like this?
I suggest opening dev tools and see what's happening there. If adding more html wasn't the case, I'd look into potential problems with recursion or creating too many objects.
I figured it out! My setSubCategory() function was calling getPhotos() which was calling setSubCategory(), and so on and so forth.
Turns out it was a simple never-ending loop. Face-palm.
Am trying to advance my javascript code, by using it as an object so i can call it when needed but it doesn't work. Please can someone help me out i will appreciate it.
var AppObject = {
var targetElement = "#AjaxLoadBodyContentLoader";
init: function (hashUrl, defaultBack){
if(hashUrl != defaultBack && hashUrl != ""){
var LoadHashUrl = hashUrl+' #AjaxLoadBodyContentLoader';
$('#AjaxLoadBodyContentLoader').load(
LoadHashUrl,
{"async_content" : "true", "PrevLink" : defaultBack}
);
}
},
asyncShowContent: function(){
/*$.getScript("external.js");*/
$(this.targetElement).show('normal', this.asyncPregressBar);
},
asyncPregressBar: function(){
$('#preloader').fadeOut();
$('#status').fadeOut();
},
asyncLoader: function(){
$(this.targetElement).load(
this.linkPath,
{"async_content" : "true", "PrevLink" : this.PrevLink},
function(responseTxt, statusTxt, xhr){
this.asyncShowContent();
console.log("Status: " + xhr.status + " | Text: " + xhr.statusText);
}
);
},
asyncExtecute: function(e){
var targetUrl = e.target.href;
if(typeof targetUrl == 'undefined' || targetUrl == ""){
targetUrl = $(this).attr('href');
}
var linkPath = targetUrl + ' ' + this.targetElement;
var PrevLink = $(this).attr('data-page-link');
window.location.hash = targetUrl;
$('#preloader').fadeIn();
$('#status').fadeIn();
$(this.targetElement).hide('fast',this.asyncLoader);
}
}
Using the above code without adding it inside AppObject={}, work very fine, but i want to advance it and learn more how to use javascript object.
Usage
$(function(){
AppObject.init(
window.location.hash.substr(1),
location.href.replace(location.hash,"")
);
$(document).on('click', 'a.LoadPage', function(e){
AppObject.asyncExtecute(e);
});
});
As #musefan says in a comment, you have a syntax problem:
This is wrong:
var AppObject = {
var targetElement = "#AjaxLoadBodyContentLoader";
...
}
This is a variable declaration:
var targetElement = "#AjaxLoadBodyContentLoader";
Inside an object, you need to use key/value pairs:
var AppObject = {
targetElement : "#AjaxLoadBodyContentLoader",
...
}
EDIT: e is undefined
e should be your event, you need it in asyncExtecute,
var AppObject = {
asyncExtecute: function(e){
e.preventDefault(); // Add this line, to prevent the browser to immediately navigate to other window
var targetUrl = e.target.href;
...
}
}
$(function(){
...
$(document).on('click', 'a.LoadPage', function(e){
AppObject.asyncExtecute(e); // Here you are passing the event object to asyncExtecute
});
});
Problem is the way you are adding property to your object. Please add it as below:
var AppObject = {
targetElement: "#AjaxLoadBodyContentLoader",
//remaining code---
};
I have check some others post, and document myself but I dont know what is the problem here.
I have 2 image (would like to have like 20 at the end) where you can click on an icon and show and hide and image in the webpage. If you click on image A it should show image A, if you click on image B image A should hide and image B should be sown.
var firsttime = 1;
var $lastletter;
$(function() {
$('#A').click(function() {
if (firsttime = 0){
$lastletter.toggle();
$('#AL').toggle();
$lastletter = $( '#AL' );
}
else
{
firsttime = 0;
$('#AL').toggle();
$lastletter = $( '#AL' );
}
});
});
$(function() {
$('#B').click(function() {
if (firsttime = 0){
$lastletter.toggle();
$('#BL').toggle();
$lastletter = $( '#BL' );
}
else
{
firsttime = 0;
$('#BL').toggle();
$lastletter = $( '#BL' );
}
});
});
This is the solution im using:
$(function() {
$('.imgLetter').click(function() {
if (lastletter != this.id) {
$('#' + lastletter + 'L').toggle();
lastletter=this.id;
}
$('#' + this.id + 'L').toggle();
});
});
Assuming you're conventionally assigning the "last letter" by appending an "L" to the ID: this could get a lot simpler. Decorate all of your #<x> elements with a class name that makes it easy to select all of them at once. I'm going to choose "letter".
I don't think you even need to track the "first time". It sounds like you just want one element to toggle another. That would look like:
$(function() {
$('.letter').click(function() {
$('#' + this.id + 'L').toggle();
});
});
I am trying to develop functionality for repeatable blocks within my web form, the issue being the buttons do nothing when I click them I have tested them in the console and they do work, they just dont do anything and am unsure why, been working on this for 2 days and am at a standstill, anyone who can point me in the right direction would be much appreciated.
It should generate the fields contained within that field set and generate a identical empty field set, and not sure whats wrong with the plus or minus functions.
$('input, fieldset').each(function(){
if ($(this).attr('data-maxOccurs') != 1){
$(plusMinusButtons).insertAfter(this);
}
});
$('.glyphicon-plus-sign').hover(function(){
$(this).addClass('green');
},
function(){
$(this).removeClass('green');
}
);
$('.glyphicon-minus-sign').hover(function(){
$(this).addClass('red');
},
function(){
$(this).removeClass('red');
}
);
$('body').on("click", '.glyphicon-plus-sign', function (){
prevInput = $(this).prev('input');
count = $(prevInput).attr('data-count');
countIncremented = count++;
br = '<br/><br/>';
inputElement = '<input type="'+$(prevInput).attr("type")+'" name="'+$(prevInput).attr("name")+countIncremented+'" data-count="'+countIncremented+'"/>';
$(br + inputElement + plusMinusButtons).insertAfter('.'+$(prevInput).attr("name")+':last');
}
);
$('body').on("click", '.glyphicon-minus-sign', function (){
prevInput = $(this).prev('input');
$(this).remove(prevInput).remove(this);
}
);
$("button").click(function(){
console.log("here");
x=$('#form').serializeArray();
$.each(x, function(i, field){
console.log(field.name + ":" + field.value + " ");
});
});
});
And here is the JSfiddle: Fiddle
The code Used in order to duplicate the field set.
$('body').on("click ", '.glyphicon-plus-sign', function() {
console.log("here ");
prevInput = $(this);
count = $(prevInput).attr('data-count=')||0;
countIncremented = count++;
br = '<br/><br/>';
$($(this).parent()).clone().insertAfter($(this).parent());
I'm building on a WordPress theme and wants to load posts and pages with AJAX. I got that sorted out through the snippet below, but now I just need to suppress the function when clicking on the logo, obviously linking to the home url. So when clicking on the logo it should force a normal reload, instead of using the function.
I figure it would have something to do with "if hasClass(logo) then use default"... Yeah, I'm fairly new to JavaScript, but I have been searching a lot, so any help in the right direction will be much appreciated. Thanks!
The snippet:
$(".home li.home").removeClass("home").addClass("current_page_item");
var $wrapperAjax = $("#wrapper-ajax"),
URL = '',
siteURL = "http://" + top.location.host.toString(),
$internalLinks = $("a[href^='"+siteURL+"']"),
hash = window.location.hash,
$ajaxSpinner = $("#ajax-loader"),
$el, $allLinks = $("a");
function hashizeLinks() {
$("a[href^='"+siteURL+"']").each(function() {
$el = $(this);
if ($.browser.msie) {
$el.attr("href", "#/" + this.pathname)
.attr("rel", "internal");
} else {
$el.attr("href", "#" + this.pathname)
.attr("rel", "internal");
}
});
};
hashizeLinks();
$("a[rel='internal']").live("click", function() {
$ajaxSpinner.fadeIn();
$wrapperAjax.animate({ opacity: "0.1" });
$el = $(this);
$(".current_page_item").removeClass("current_page_item");
$allLinks.removeClass("current_link");
URL = $el.attr("href").substring(1);
URL = URL + " .entry";
$wrapperAjax.load(URL, function() {
$el.addClass("current_link").parent().addClass("current_page_item");
$ajaxSpinner.fadeOut();
$wrapperAjax.animate({ opacity: "1" });
hashizeLinks();
});
});
$("#searchform").submit(function(e) {
$ajaxSpinner.fadeIn();
$wrapperAjax.animate({ opacity: "0.1" });
$el = $(this);
$(".current_page_item").removeClass("current_page_item");
$allLinks.removeClass("current_link");
URL = "/?s=" + $("#s").val() + " .entry";
$wrapperAjax.load(URL, function() {
$ajaxSpinner.fadeOut();
$wrapperAjax.animate({ opacity: "1" });
hashizeLinks();
});
e.preventDefault();
});
if ((hash) && (hash != "#/")) {
$("a[href*='"+hash+"']").trigger("click");
}
I'm guessing you mean the script from this line: $("a[rel='internal']")
In that case, $("a[rel='internal']").not('.logo') should do the trick.
I should've read the entire code. Replace $("a[href^='"+siteURL+"']") with $("a[href^='"+siteURL+"']").not('.logo') as well.
If it has the class .logo you could add this at the top of the function:
if ($(this).hasClass('logo')) return true;
See the simple example.