Class of ID Change based on URL - URL Based Image Swap - - javascript

What I'm trying to achieve:
Based on URL (ie., foo.com/item1), the div element "logoswap" receives a different class.
The following is the code I put together but it seems completely wrong. I'm not a JS pro by any means, XHTML/CSS is more my speed (some PHP)... I cannot use PHP, even if it is possible in PHP (and I know it is because I have a PHP version of what I need done already, but I can't call the PHP properly.
I'm really just trying to get a different logo to show up based on the directory/url... It doesn't have to be a background element called in by the CSS class necessarily, I just need a different image to load based on the aforementioned url variable...
$(function() {
var url = location.pathname;
if(url.indexOf('item1') > -1) {
document.getElementById("logoswap").className += " class1";
}
elseif(url.indexOf('item2') > -1) {
document.getElementById("logoswap").className += "class2";
}
elseif(url.indexOf('item3') > -1) {
document.getElementById("logoswap").className += "class3";
}
elseif(url.indexOf('item4') > -1) {
document.getElementById("logoswap").className += "class4";
}
elseif(url.indexOf('item5') > -1) {
document.getElementById("logoswap").className += "class5";
}
else {
document.getElementById("logoswap").className += "class1";
}
});
That's what I have... Ugly I'm sure.
That's why I'm here though, I definitely need some help.

Assigning CSS Class By URL Pathname
A jsfiddle has been setup for
this solution.
Here is a case for using numeric expressions if they are available. This does not apply to the above question.
$(function() {
var rgx = /item(\d+)$/,
url = location.pathname,
id = (rgx.test(url)) ? url.match(rgx)[1] : '1';
$("#logoswap").addClass("class" + id);
});
UPDATE:
In light of the new details you may need an array of values, these should be derived from or exactly equal to the class names you intend to use.
$(function(){
// my favorite way to make string arrays.
var matches = "brand1 brand2 brand3".split(" "),
url = location.pathname.match(/\w+$/)[0], // get the last item
id = matches.indexOf(url),
className = matches[(id > -1) ? id : 0];
$("#logoswap").addClass(className);
});
To make this work you will need a few things in place. I will assume that the paths will end in a number as we have outlined here. The default ends with 1. You will need the images to be accessible. You need to define the styles for each possibility.
CSS Setup
#logoswap {
height : 200px;
width : 200px;
}
.class1 {
background-image : url(/path/to/default.jpg);
}
.class2 {
background-image : url(/path/to/second.jpg);
}
.brand1 {
background-image : url(/path/to/brand/1/logo.jpg);
}
...
Without jQuery
if you do not have jQuery in your code you may need to use window.onload.
(function(){
var old = window.onload;
window.onload = function(){
old();
var r = /item(\d+)$/,
url = location.pathname,
id = (r.test(url)) ? url.match(r)[1] : '1';
document.getElementById('logoswap').className += "class" + id;
};
})()
I just want to take a moment here to
encourage anyone who is doing this
type of code to get used to Regular
Expressions and learn them. They are
far and away the most frequently used
cross language part of my development
arsenal.

There's nothing that wrong with what you have. You could tidy it up with something like below.
$(function() {
var url = location.pathname;
var logo = document.getElementById("logoswap");
var i = 6;
logo.className = "class1";
while(i--)
{
if(url.indexOf("item" + i) > -1) {
logo.className = "class" + i;
}
}
});
Hope this helps.

Using just HTML/CSS, you could add (or append via javascript) an id to the body of the page:
<body id="item1">
Then in your CSS, create a selector:
#item1 #logoswap {
// class1 CSS
}

Related

How to add alt and title attributes along with image in quill editor

var range = this.quill.getSelection();
var value = prompt('please copy paste the image url here.');
if(value){
this.quill.insertEmbed(range.index, 'image', value, Quill.sources.USER);
}
I solved the problem of adding images by linking in the quill editor with the api code above. But I couldn't find how to add alt and title properties with the help of api. I can edit it later with the following javascript code, but I need to edit it at the image insertion stage.
if (e.target.tagName=='IMG') {
console.log(e.target.tagName)
var el = e.target;
el.setAttribute("title", "asdasdasd");
}
})
Also, when I add a or tag to the editor, it is surrounded by a p tag and cannot be edited. It puts everything in the p tag and doesn't allow tags like br. How can I solve these problems?
Sorry for the bad english.
There seems to be no easy and elegant way to do it. The API does not allow it (or I have not seen it) and the source code does not seem to be documented.
I propose this code while waiting for a better solution.
It is based on a solution to observe dynamically created elements. I have added the caption of the title and alt attribute.
To get the code to work, you will need to explain the following to your users:
They must write the title and alt in this format wherever they want to insert the image:
%title% A title %alt% An alternative text
Then, they must select that same:
%title% A title %alt% An alternative text
With that text selected they must click the image button and open the image.
Notice, at the moment, you cannot escape "%alt%", so you cannot use the "%alt%" expression within the value of an attribute.
Example:
%title% The title is before %alt% %alt% the %alt% attribute
This causes an unwanted alt attribute.
Paste this code after creating an editor.
BTW, it is only valid for the first editor that exists.
var FER_alt;
var FER_title;
function FER_callback(records) {
records.forEach(function (record) {
var list = record.addedNodes;
var i = list.length - 1;
for ( ; i > -1; i-- ) {
if (list[i].nodeName === 'IMG') {
if(FER_title.length > 0){
list[i].setAttribute('title',FER_title)
}
if(FER_title.length > 0){
list[i].setAttribute('alt',FER_alt)
}
}
}
});
}
var FER_observer = new MutationObserver(FER_callback);
var FER_targetNode = document.querySelector('.ql-editor')
FER_observer.observe(FER_targetNode, {
childList: true,
subtree: true
});
function FER_getTitleAlt(){
var selection = quill.getSelection();
var texto =quill.getText(selection.index,selection.length);
var titleE = texto.search("%alt%")
FER_title = texto.substr(7,titleE-7);
var titleI = titleE + 5
FER_alt = texto.substring(titleI)
}
var FER_imageboton = document.querySelector(".ql-image")
FER_imageboton.addEventListener("click",FER_getTitleAlt)
Instead of insertEmbed you can use getContents and setContents.
let delta = {
ops: [
{
attributes: {
alt: yourAltValue
},
insert: {
image: yourSrcValue
}
}]
};
let existingDelta = this.quill.getContents();
let combinedDelta = existingDelta.concat(delta);
this.quill.setContents(combinedDelta);
Extends Image blot and override the create method
const Image = Quill.import('formats/image');
class ImageBlot extends Image {
static create(value) {
const node = super.create(value);
if (typeof value === 'string') {
node.setAttribute('src', this.sanitize(value));
node.setAttribute('alt', this.sanitize(value).split('/').reverse()[0]);
}
return node;
}
}
Quill.register(ImageBlot);
In this example, we set alt attribute with image's basename

Tweak the load event on chrome extension

I have created a google chrome extension to replace certain images from third party websites. I have implement all the programming part but one of my requirements states that
On a slower net connection the original images should not be visible
until it’s replaced by the new images
I am not sure wether it is achievable or not. I want to know what sort of event I should attach here. Can experts give their input on this?
This is the work I have done.
// get current websites base url
var current_website = window.location.href;
//run the code on specific pages
if ($.inArray(current_website, config.target_websites) != -1) {
config.image_config.forEach(function (obj) {
var src = obj.src;
var target = obj.target;
/**find all the occurances in the <img> tag */
var key = 'img[src*="' + src + '"]';
var img = $(key);
/**replace it with the target image*/
img.attr('src', target);
/** check the inline CSS*/
$("[style*=background-image]").css('background-image', function (i, oldimg) {
return oldimg.indexOf(src) == -1 ? oldimg : 'url(' + target + ')';
});
/***check all the external styles for the image*/
$('*').each(function () {
if ($(this).css('background-image').indexOf(src) != -1) {
$(this).css('background-image', 'url(' + target + ')');
}
});
});
}
Since you're already using jQuery, if you're not opposed to a small library (7.25 KB), you can use the jQuery plugin imagesloaded.
Basic usage:
// options
$('#container').imagesLoaded( {
// options...
},
function() {
// your code to run after load
}
);
Then you could do a simple $('img').hide() on load, and $('img').show() after all images have loaded on your particular images.
You can see in the demo that it works for images which have been inserted dynamically into the page as well, which would meet your requirement for that the images of your key be hidden until replaced.
http://imagesloaded.desandro.com/

turning CSS on / off globally

My goal is to have a button (controlled by a javascript function) that would toggle the entire CSS on the website on and off. I thought this was a common practice and was surprised when I couldn't find a complete solution here or on the web.
Here is what I got.
$("#button").click(function() {
var css = (document.styleSheets[0].enabled = true);
if (css == true)
{
document.styleSheets[0].disabled = true;
css = (document.styleSheets[0].enabled = false);
}
else if (css == false)
{
document.styleSheets[0].disabled = false;
}
});
A simple Jquery function that targets the button by ID and performs an if test. I could've ommited the variable, but this way I am able to check the value easily in console.log. I am able to turn the CSS off, but not back on. The program doesn't even get to the else condition.
I am aware that the else if is not really appropriate, but with just else (and even just with another if condition) the function doesn't run at all.
Second option that I thought of, and which might be much easier is just dynamically changing the contents of the link href attribute, where the path to the css file is given.
But I am struggling to target the href element with Javascript.
This is a simple Boolean toggle so write it as a simple toggle
$("#button").click(function() {
var sheet = document.styleSheets[0];
sheet.disabled = !sheet.disabled;
});
As for why your code isn't working as is,
var css = (document.styleSheets[0].enabled = true);
// same as
var css;
document.styleSheets[0].enabled = true;
css = true;
which means
if (css == true)
// same as
if (true == true)
which always holds so you'll always follow this code path
Well, for one you need to loop through all of the stylesheets.
Also, you can save some lines of code by using a counter, then on each button click increment the counter and use the % modulo operator to turn that into a 1 or a 0, which you can then coerce a boolean from using !!.
var count = 0;
var sheets = document.styleSheets;
$("#button").click(function() {
for(var i in Object.keys(sheets)) sheets[i].disabled = !!(++count % 2);
});
.demo {
background: #888;
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="demo">Some Text</div>
<button id="button">Click It</button>
Your problem is that you are doing an assignment when you should be doing an equality check.
You have
var css = (document.styleSheets[0].enabled = true);
But you are really trying to do an equality check, i.e.,
var css = (document.styleSheets[0].enabled == true);
Notice the extra =. The single = does an assignment, so your current code is equivalent to this:
document.styleSheets[0].enabled = true
var css = document.styleSheets[0].enabled; // i.e., true
Because you set enabled to true, your if (css == true) condition is always satisfied, so your code always turns the CSS off and never turns it back on.
The fix, as Paul S. wrote in his answer, is just to toggle the value of document.styleSheets[0].disabled, as in:
$("#button").click(function() {
document.styleSheets[0].disabled = !document.styleSheets[0].disabled;
});
There's no need to set and track a new property enabled.
The issue seems to be that you are doing assignment, and not comparison, on this line:
var css = (document.styleSheets[0].enabled = true);
It should be
var css = (document.styleSheets[0].enabled == true);
Probably simpler, since you have a jquery tag on the question, to just do:
$stylesheets = $('link[rel="stylesheet"]');
$("#button").click(function() {
$stylesheets.attr('disabled', !$stylesheets.attr('disabled'));
});
If you want to modify every href in your DOM,
just use
$('a[href*=]').each(function () {
var $this = $(this);
$this.attr('href', $this.attr('href').replace();
});

Change background image of a div

I have 4 pages. for example: here.com/, here.com/page1/, here.com/page2/, here.com/page3/
all 4 pages is using the same template (i didn't write the template), and it has a top box with a background image. something like this:
<div id="topbox">some text here</div>
the css:
#topbox {background:url('path/to/image/here.jpg') no-repeat};
Problem is all 4 pages is using the same image since it has the same id #topbox, and I'm not able to go in and change the structure of the pages.
Is there a way that I can use js to detect the url path, say if it's at root then background will be defaultpic.jpg, if /page1/ will use picture1.jpg, /page2/ will use picture2, /page3/ will use picture3.jpg
From the information you've given, I'd suggest:
var pagePicture = {
'page1' : 'picture1',
'page2' : 'picture2',
'page3' : 'picture3'
}
var page = window.location.pathname.replace(/^\//,'').split('/').shift();
document.getElementById('topbar').style.backgroundImage = (pagePicture[page] || 'default') + '.jpg';
References:
Array.prototype.shift().
HTMLElement.style.
Location API.
String.replace().
String.prototype.split.
Window.location.
follow the below steps. hope it will help you as a guidance.
get the page URL using:
var currentPage = document.URL;
use the above url string to identify your particular page (you may need to use substring() to extract it.)
use switch/case or conditional block to assign the correct image to correct page.
shouldn't be that complex.
Used js detection isn't a good choise apart if you can't modify your div (unique include).
In case when you can add class in your div:
<div id="topbox" class="page1">
And in your CSS:
#topbox.page1 {background:url('path/to/image/picture1.jpg') no-repeat};
Repeat this procedure for all your pages.
JS detection case :
<script type="text/javascript">
window.onload = function() {
var path= window.location.pathname.split( '/' );
var page = path[path.length - 1];
var matchPageNumb = page.match(/([0-9]+)/g);
if( matchPageNumb.length ) {
var node = document.getElementById('topbox');
if( node !== null ) {
var bgURL = "url('path/to/image/picture" + matchPageNumb[matchPageNumb.length-1] +".jpg') no-repeat";
node.style.background = bgURL;
}
}
}
</script>
Below code should do what you want:
function getPictureForPage() {
var url = document.URL; // for example: http://www.here.com/page2/mypage.html
var page = url.substring(20).split('/')[0]; // Stripping 'http://www.here.com/' from the url, then splitting on '/' to split the remaining url, and get the first element ('page2')
switch (page) {
case 'page1':
return 'picture1.jpg';
case 'page2':
return 'picture2.jpg';
case 'page3':
return 'picture3.jpg';
}
return 'defaultpic.jpg';
}
document.getElementById('topbox').style.background = "url('" + getPictureForPage() + "')";
I was able to get it to work, by inserting another css file after the existing one - to only the page i want to change the bg, and it overwrite the existing 'topbox' class.
#topbox {backgroundurl('path/to/image/file.jpg') !important;
running out of time, but this work. not sure if this's the right way to do it, but it works ... for now. i'll visit back and use the codes was provided here and apply to the page.
thanks for all your help,
As you are unable to go to the html, you can get this solved by 2 ways.
Add class to div with id topbox dynamically from js file depending on the url and applying background css to respective class.
jQuery Code
var url = window.location.pathname;
var divCls = '';
switch(url) {
case 'here.com/page1/': divCls = 'page1';
break;
case 'here.com/page2/': divCls ='page2';
break;
case 'here.com/page3/': divCls ='page3';
break;
case 'here.com/page4/': divCls ='page4';
break;
default: divCls ='page';
break;
}
$("#topbox").addClass(divCls);
CSS
#topbox.page1 { background-image: url(../page1.jpeg); }
#topbox.page2 { background-image: url(../page2.jpeg); }
#topbox.page3 { background-image: url(../page3.jpeg); }
#topbox.page4 { background-image: url(../page4.jpeg); }
Directly applying the background image from javascript
jQuery Code
var weburl = window.location.pathname;
var chksplit = weburl.split('/');
switch(chksplit[0]) {
case 'page1': $("#topbox").css("background-image": "url(../page1.jpeg)");
break;
case 'page2': $("#topbox").css("background-image": "url(../page2.jpeg)");
break;
case 'page3': $("#topbox").css("background-image": "url(../page3.jpeg)");
break;
case 'page4': $("#topbox").css("background-image": "url(../page4.jpeg)");
break;
}

Highlight a button based on location

I'm trying to highlight a navigational button (in a menu) based on the page being viewed. Here is what I have so far:
var loca = String(document.location.href);
// Get document location and specific page.
if (loca) {
if(loca.search(RegExp("((/[\w]*)\.php)")) != -1) {
activate(loca.match(RegExp("((/[\w]*)\.php)").split("/").join("")));
} else {
activate("home");
}
}
// Activate a button
function activate(bName) {
$(".button[name=" + bName + "]").css({
"border-left": "1px solid white",
"border-right": "1px solid white"
});
}
What I want to happen is this:
Get URL of page
Get the specific file name of page, and if not found, then we are on the homepage.
Using jQuery, I try to find the name of the button, and if the name matches the filename, then highlight it.
Thing is, this only highlights the "Home" button. What am I doing wrong? Also, if you have any suggestions on how I can better accomplish this, please let me know!
I would get the filename like this, instead:
var pathname = window.location.pathname.split("/");
var filename = pathname[pathname.length-1].split(".")[0];
alert(filename);
Your regular expression is incorrect.
var loc_match = window.location.href.match(/(\w+)\.php/);
activate(loc_match ? loc_match[1] : "home");
I don't have a solution but I would assume the regex is flawed. Did you try to store the result in a variable and console.log it?
I've actually implemented something like this. Here's my code:
var currentPage = window.location.pathname.toLowerCase().split('/').reverse()[0].split('#')[0].split('?')[0];
if (!currentPage || currentPage == '')
{
currentPage = 'default.aspx';
}
$('#nav li').removeClass('current').each(function() {
var href = $(this).find('a').first().attr('href');
if (href && href.toLowerCase().indexOf(currentPage) >= 0)
{
$(this).addClass('current');
}
});
This takes into account any query strings or searches may be in the URL. Using reverse() may not be the most efficient way of doing it, but it certainly works.
When you declare your regexp as new RegExp object, you have to use double backslash escaping symbols (instead one backslash, when you just assign literal like var a = /\w/i; );
So, your code should work after some reg exp correction:
var loca = document.location.href;
var pattern = new RegExp("[\\w]*(?=\\.php)","i");
// Get document location and specific page.
if(pattern.test(loca)) {
activate(pattern.exec(loca));
} else {
activate("home");
}
// Activate a button
function activate(bName) {
$(".button[name=" + bName + "]").addClass('active')
}
And as already said, it's easier to assign class to your active element.

Categories

Resources