Generating CSS Selectors with JavaScript

Presently, I am attempting to devise CSS Selectors using JavaScript specifically tailored for particular web browsers and mobile devices. The current method in place is as follows:

// IDENTIFY BROWSER AND APPLY CORRESPONDING CSS METHOD
    function getBrowserName() {
        var name = "Unknown";
        if(navigator.userAgent.indexOf("MSIE")!=-1){
            name = "msie";
        } if(navigator.userAgent.indexOf("Trident")!=-1){
            name = "msie";
        } if(navigator.userAgent.indexOf("Edge")!=-1){
            name = "msie";
        } else if(navigator.userAgent.indexOf("Firefox")!=-1){
            name = "firefox";
        } else if(navigator.userAgent.indexOf(" OPR/")>=0){
            name = "opera";
        } else if(navigator.userAgent.indexOf("Chrome") != -1){
            name = "chrome";
        } else if(navigator.userAgent.indexOf("Safari")!=-1){
            name = "safari";
        }
        return name;   
    }

    if (getBrowserName() != "Unknown"){
        document.getElementsByTagName('html')[0].className += "is-" + getBrowserName(name);
    }

The above method can be called by

.is-(browser-name element-selector { css }
. However, the same implementation does not seem to function effectively for mobile devices. Here's a glimpse at my code...

var mobile = (/iphone|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase()));  
if (mobile) { 
    document.getElementsByTagName('html')[0].className += "is-mobile";
}

In other instances, I have been utilizing jQuery for tasks outside of the if (mobile) segment which has proven successful. Nonetheless, I am keen on streamlining this process using standard CSS and JavaScript. Although a functional code snippet cannot be provided since compatibility is contingent upon specific browser usage, an illustrative sample has been included below.

Is there anyone able to identify why the code functions appropriately for various browsers but encounters obstacles when targeting mobile devices? Appreciate any assistance!

// FUNCTIONAL
function getBrowserName() {
  var name = "Unknown";
  if (navigator.userAgent.indexOf("MSIE") != -1) {
    name = "msie";
  }
  if (navigator.userAgent.indexOf("Trident") != -1) {
    name = "msie";
  }
  if (navigator.userAgent.indexOf("Edge") != -1) {
    name = "msie";
  } else if (navigator.userAgent.indexOf("Firefox") != -1) {
    name = "firefox";
  } else if (navigator.userAgent.indexOf(" OPR/") >= 0) {
    name = "opera";
  } else if (navigator.userAgent.indexOf("Chrome") != -1) {
    name = "chrome";
  } else if (navigator.userAgent.indexOf("Safari") != -1) {
    name = "safari";
  }
  return name;
}

if (getBrowserName() != "Unknown") {
  document.getElementsByTagName('html')[0].className += "is-" + getBrowserName(name);
}

// ISSUE WITH MOBILE
var mobile = (/iphone|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase()));

if (mobile) {
  document.getElementsByTagName('html')[0].className += "is-mobile";
}

// FUNCTIONAL
if (mobile) {
  $(".about-text").css("width", "90%");
  $("body").css("font-size", "50px");
  $("section").css("padding-top", "160px");
}
/* FUNCTIONS */
.is-msie hr {
  margin: 50px 0 10px 0;
}


/* ISSUE */
.is-mobile hr {
  margin: 50px 0 10px 0;
}
<!--REPEATING TABLE WITH HR FOR SEPARATORS -->

....(content removed for brevity)
                    
</div>

Answer ā„–1

To ensure proper functionality, make sure there is a space before "is-mobile" in the class name. The className attribute should consist of space-separated values, so your current setup may not work correctly on mobile devices.

One way to fix this issue is by splitting the existing class names into an array, adding the desired class, and then combining them back with spaces:

(document.getElementsByTagName('html')[0].className || "").split(" ").concat(["is-mobile"]).join(" ");

If your browsers support ES6 features, using a Set can be a better approach to handle duplicate class names:

let htmlElement = document.querySelector('html')

// Utilize a Set to prevent duplicates.
let classNames = new Set((htmlElement.className || '').split(' '))
classNames.add('is-safari')
classNames.add('is-mobile')

// Convert the set of class names to an array and combine them.
htmlElement.className = Array.from(classNames).join(' ')

console.log(htmlElement.className)

Answer ā„–2

The issue stemmed from the spacing initially, but thanks to all of you for assisting me in resolving that. Surprisingly, the main problem lied in replacing "html" with "body" in that specific line, resulting in the updated code snippet below:

document.getElementsByTagName('body')[0].className += " is-mobile";

I appreciate all your contributions! Stay tuned for a revised version of the code tomorrow.

UPDATE: Strangely enough, after making some adjustments in my document structure, the original code actually started working...despite not functioning as intended previously. I'll be sharing the new format involving multiple files, but here's how my code appears now:

First file assigning CSS Classnames. Called in the header section

// ADD CLASSNAME FOR MOBILE DEVICES
var mobile = (/iphone|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase()));  

if (mobile) { 
    document.getElementsByTagName('html')[0].className += " is-mobile";
}

// $(".about-text").css("width", "90%");

// ADD CLASSNAME FOR APPLE DEVICES
var appleDevice = (/iphone|ipod/i.test(navigator.userAgent.toLowerCase()));

if (appleDevice) {
    document.getElementsByTagName('html')[0].className += " is-apple";
}

// CHECK BROWSER AND ADD CORRESPONDING CLASSNAME
function getBrowserName() {
    var name = "Unknown";
    if(navigator.userAgent.indexOf("MSIE")!=-1){
        name = "msie";
    } if(navigator.userAgent.indexOf("Trident")!=-1){
        name = "msie";
    } if(navigator.userAgent.indexOf("Edge")!=-1){
        name = "msie";
    } else if(navigator.userAgent.indexOf("Firefox")!=-1){
        name = "firefox";
    } else if(navigator.userAgent.indexOf("OPR/")>=0){
        name = "opera";
    } else if(navigator.userAgent.indexOf("Chrome") != -1){
        name = "chrome";
    } else if(navigator.userAgent.indexOf("Safari")!=-1){
        name = "safari";
    }
    return name;
}

if (getBrowserName() != "Unknown"){
    document.getElementsByTagName('html')[0].className += " is-" + getBrowserName(name);
}

Second file removing elements from DOM based on device or browser. Included before other script tags in the footer for improved load times.

var music = document.getElementById("music");
var musicLink = document.getElementById("music-link");
var photos = document.getElementById("photos");
var photosLink = document.getElementById("photos-link");

if (mobile) {
    music.parentNode.removeChild(music);
    musicLink.parentNode.removeChild(musicLink);
    photos.parentNode.removeChild(photos);
    photosLink.parentNode.removeChild(photosLink);
}

if (getBrowserName() == "msie") {
    photos.parentNode.removeChild(photos);
    photosLink.parentNode.removeChild(photosLink);
}

Additional details are contained in a separate JS file utilizing jQuery and may not be directly relevant to this discussion. Thanks once again for the assistance provided by everyone!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Show the JSON data returned

Looking for a way to display the JSON response in a JSP page using AJAX... function doAjaxPost() { var name = $('#name').val(); var password = $('#password').val(); var gender = $('#gender').val(); var abo ...

Add both single (' ') and double (" ") quotes within the `document.querySelector` code

Given an array of attributes like the following: let elementsArray = [ '[name="country_code"]', '[name="user_tel_code"]', '[name="countryCode"]' ]; If I aim to iterate through them using a ...

Tips for displaying a loading indicator above a form

I've been struggling to figure out how to display a loading indicator on top of my form without messing up the styling... https://i.sstatic.net/FFCRW.png My goal is to show the loading indicator when any action, like deleting an item or changing qua ...

Utilize various designs on Bootstrap cards

In my Angular 9 project, I'm utilizing Bootstrap 4 cards with NGFOR to dynamically display elements fetched from the database. I have an array containing different styles for the card border, and I want each card to apply a random style from this arr ...

Is there a way to automatically make required fields turn red upon form load using model validations in MVC?

After implementing Model validations and remote attribute validation, I noticed that all mandatory fields turn red when the submit button is clicked. Is it possible for all mandatory fields to turn red upon form load instead? ...

Is it possible to use JavaScript or jQuery to call a WCF Service and retrieve a collection of System.IO.Stream objects?

I am developing a WCF service that will be utilized by plain JavaScript on the client side, as well as some jQuery JavaScript. 1) How can I set up the plain client JavaScript to call the WCF Service in a manner that retrieves a collection of System.IO.Str ...

Vue JS - Troubleshooting Checkbox Validation Error During Form Submission

When a user fills out my registration form, there is a checkbox to confirm acceptance of the terms and conditions. Currently, the validation error for this checkbox appears immediately upon hitting submit, even though the checkbox starts as unchecked. The ...

Looking for a way to choose a button with a specific class name and a distinct "name" attribute using jquery?

I am currently working on developing a comment system. As part of this system, I want to include a toggle replies button when a user posts a reply to a comment. However, I only want this button to be displayed if there are no existing replies to the commen ...

Building applications with Vue.js and Framework7 while incorporating the powerful Axios library

I am inexperienced with framework7 and vuejs. Can someone confirm if I am importing it correctly? Additionally, how can I make axios accessible from other pages? Here is my main.js file. Iā€™m uncertain if the import process is accurate or if any steps ar ...

Switching Primary Menu Selection When Scrolling Through Various Menu Options

I need help with changing the active class of links on my single page scrolling website. I found some useful code snippets for smooth scrolling and updating the active class on scroll or click events: $(document).ready(function () { $(document).on(" ...

Tips for Aligning Several Images Horizontally in an Article

Does anyone know how to center pictures in an article horizontally? I've tried various techniques without success. If it would be helpful, I can share the CSS I currently have. However, I am open to starting from scratch with the CSS as well since I ...

Discover the size of an image using JavaScript by accessing innerHTML

I'm currently working on a unique AJAX function that retrieves image URLs without using node append for insertion. Instead, I opted to utilize innerHTML, but this has posed challenges in accurately obtaining the file dimensions. My current approach i ...

Redirect the "Add To Cart" button to a unique custom page on Magento or incorporate a new button on the product page in Magento

Currently, I am in the process of enhancing a Magento website. My goal is to integrate an image editor just after the product page, before the user proceeds to the add to cart and checkout pages. Specifically, I aim to change the label of the "Add To Cart" ...

The default selection in res.format is not being properly recognized

When I make a request with the accept header set as "application/json, text/javascript, */*; q=0.01", the response is always in HTML format instead of the default format specified. It seems like something is missing here. Given that the header does not spe ...

Converting an array of images into blob format and displaying it using PHP

I am attempting to convert an array of images into blob format and then send it to a PHP script for data processing. However, I am encountering an issue where the array of blobs is not being sent correctly, and I am unsure why this is happening. Here is my ...

Using the rvest package to extract data from a password-protected website without the need to log in every time the loop iter

My goal is to extract data from a password-protected website using the rvest package in R. Currently, my code logs in to the website in each iteration of a loop, which will be repeated approximately 15,000 times. This approach seems inefficient, but I have ...

Ways to display an image overlay on hover using sprite sheets

Is there a way to make a line appear, around 10px in size, when hovering over an image at the bottom of that image? I came across this effect on MTV's website within their "You would also like these" section below each post. They utilized css-backgro ...

Arranging arrays within a JSON object in a new order

var data = { chart : 'rank', labels: [ { 0: 'First Option' 1: 'Second Option', 2: 'Third Option', 3: 'Fourth Option', 4: 'Fifth Option' } ], ro ...

Disabling and Re-Enabling Mouse Interaction on a jQuery UI Slider

Can you disable mouse clicks and then re-enable them for a jQuery UI slider? The jQuery examples don't seem to work Sample code To initialize a slider with the disabled option specified: $( ".selector" ).slider({ disabled: true }); To get or set ...

Struggling with aligning mat-icon in the center using HTML and CSS?

My issue is that the mat-icon in my generated columns is not center aligned. What could be causing this? When using ngFor to generate my datatable columns dynamically, none of them align correctly. The mat-icon inside my DIV defaults to left alignment. ...