Using certain javascript code on mobile devices only? - javascript

I am trying to code a way that only allows this particular javascript code to run on screen sizes that are less than 900 pixels. This code is used to set up a simple left and right navigation button on mobile devices. However, when I try and use matchMedia it totally messes up my code but does not throw any errors. How would you approach this issues?
var flavorScroll = (function() {
let widthMatch = window.matchMedia("(min-width: 901px)");
if (widthMatch.matches) {
var flavorBox1 = document.body.querySelector('#flavor-box-1');
var flavorBox2 = document.body.querySelector('#flavor-box-2');
var flavorBox3 = document.body.querySelector('#flavor-box-3');
var flavorBox4 = document.body.querySelector('#flavor-box-4');
var buttonRight = document.body.querySelector('#flavorButtonRight');
var buttonLeft = document.body.querySelector('#flavorButtonLeft');
var step = 1;
leftButton.style.visibility = 'hidden';
function flavorDisplayer(currentStep){
if(currentStep === 1) {
flavorBox1.style.display = 'block';
flavorBox2.style.display = 'none';
leftButton.style.visibility = 'hidden';
} else if(currentStep === 2) {
flavorBox2.style.display = 'block';
flavorBox1.style.display = 'none';
flavorBox3.style.display = 'none';
leftButton.style.visibility = 'visible';
} else if(currentStep === 3) {
flavorBox3.style.display = 'block';
flavorBox2.style.display = 'none';
flavorBox4.style.display = 'none';
rightButton.style.visibility = 'visible';
} else if(currentStep === 4) {
flavorBox4.style.display = 'block';
flavorBox3.style.display = 'none';
rightButton.style.visibility = 'hidden';
}
}
buttonRight.addEventListener('click', function() {
step += 1;
flavorDisplayer(step);
});
buttonLeft.addEventListener('click', function() {
step -= 1;
flavorDisplayer(step);
});
} else {
}
})();

This is a handy util I use...
var breakpoint = {
is(s) {
const size = s.trim()
const sizes = {
xsmall: "480px",
small: "576px",
medium: "780px",
large: "992px",
xlarge: "1200px",
}
if (sizes.hasOwnProperty(size)) {
// return mq(`only screen and (min-width: ${sizes[size]})`)
return window.matchMedia(`only screen and (min-width: ${sizes[size]})`).matches
}
throw new ReferenceError(`The size ${size} is not a valid breakpoint: ${JSON.stringify(sizes)}`)
},
}
Then you can wrap your function in an if statement i.e.
if (breakpoint.is("medium")) {
...
}

Use screen.width to get the current size of the screen the user is working on. Then use that value to limit when the code is executed.
var scrn = screen.width
if (scrn < 2000) { console.log(1); };

Related

Swiper JS, swiper.destroy() doesnt work and I cant find the issue

I am trying to use Swiper JS and can't find a way to destroy the swiper when needed and using the function with $(window).resize()
Please tell me what can be the issue.
Here is my code:
$(document).ready(() => {
initTopInfoContainerSwiper()
}
$(window).resize(() => {
initTopInfoContainerSwiper()
}
let swiperInitParam = true;
let swiperDestroyParam = false;
const initTopInfoContainerSwiper = () => {
const swiper = new Swiper('#js__swipper-top-wrapper-index', {
init: false,
speed: 400,
slidesPerView: 1,
centerInsufficientSlides: true,
spaceBetween: 15,
loop: true,
});
if (window.innerWidth <= 1000) {
if (swiperInitParam) {
swiper.init();
swiperInitParam = false;
swiperDestroyParam = true;
}
}
else {
if (swiperDestroyParam) {
swiper.destroy()
swiperDestroyParam = false;
swiperInitParam = true;
}
}
}
I tried to all of this methods but none worked
if (window.innerWidth <= 1000) {
if (swiperInitParam) {
swiper.init();
swiper.enable();
swiperInitParam = false;
swiperDestroyParam = true;
}
}
else {
if (swiperDestroyParam) {
swiper.loop = false;
swiper.allowTouchMove = false;
swiper.enable = false;
swiper.enabled = false;
swiper.disable = true;
swiper.disabled = true;
swiper.allowClick = false;
swiper.allowSlidePrev = false;
swiper.allowSlideNext = false;
swiper.allowClick = false;
swiper.initialized = false;
swiper.init()
swiperDestroyParam = false;
swiperInitParam = true;
}
}
Please Help
First of all, you are calling initTopInfoContainerSwiper() on every resize. That is not a good option when you probalby just want to listen to a specific viewport width. Instead you could do something like this:
const mediaQuery = window.matchMedia(`(min-width: 1000px)`)
mediaQuery.addEventListener('change', () => {
initSwiper()
})
To destroy the swiper, you can simply say
if (window.innerWidth <= 1000) {
swiper.init();
}
else {
swiper.destroy(true, true)
}
(see here for more information).
And i also think there is no need for swiperInitParam and swiperDestroyParam unless you are accessing them somewhere else.

Self made text-to-speech in javascript doesn't work properly

We made a text-to-speech function in javascript. The only problem now is that it doesn't work properly. When the play button is pressed, it is supposed to tell everything that's within the body tags. The problem is that most of the times it's not working and when it does, it's telling also the javascript code which it's outside of the body tag. How can i fix this so that it's working everytime the play button is pressed and it's only telling everything in the body tag?
onload = function() {
if ('speechSynthesis' in window) with(speechSynthesis) {
var playEle = document.querySelector('#play');
var pauseEle = document.querySelector('#pause');
var stopEle = document.querySelector('#stop');
var flag = false;
playEle.addEventListener('click', onClickPlay);
pauseEle.addEventListener('click', onClickPause);
stopEle.addEventListener('click', onClickStop);
function onClickPlay() {
if (!flag) {
flag = true;
utterance = new SpeechSynthesisUtterance(document.querySelector('body').textContent);
utterance.lang = 'nl-NL';
utterance.rate = 0.7;
utterance.onend = function() {
flag = false;
playEle.className = pauseEle.className = '';
stopEle.className = 'stopped';
};
playEle.className = 'played';
stopEle.className = '';
speak(utterance);
}
if (paused) {
playEle.className = 'played';
pauseEle.className = '';
resume();
}
}
function onClickPause() {
if (speaking && !paused) {
pauseEle.className = 'paused';
playEle.className = '';
pause();
}
}
function onClickStop() {
if (speaking) {
stopEle.className = 'stopped';
playEle.className = pauseEle.className = '';
flag = false;
cancel();
}
}
}
else { /* speech synthesis not supported */
msg = document.createElement('h5');
msg.textContent = "Detected no support for Speech Synthesis";
msg.style.textAlign = 'center';
msg.style.backgroundColor = 'red';
msg.style.color = 'white';
msg.style.marginTop = msg.style.marginBottom = 0;
document.body.insertBefore(msg, document.querySelector('div'));
}
}
<button id=play>Play</button>
<button id=pause>Pause</button>
<button id=stop>Stop</button>
Define the DIV you want the Speech recognition to read from:
</head>
<body>
<div>
<button id=play>Play</button>
<button id=pause>Pause</button>
<button id=stop>Stop</button>
</div>
<div id="readFrom">
Just a test o my friend mplungjan
</div>
<script type="text/javascript">
window.onload = function () {
if ('speechSynthesis' in window)
with (speechSynthesis) {
var playEle = document.querySelector('#play');
var pauseEle = document.querySelector('#pause');
var stopEle = document.querySelector('#stop');
var flag = false;
playEle.addEventListener('click', onClickPlay);
pauseEle.addEventListener('click', onClickPause);
stopEle.addEventListener('click', onClickStop);
function onClickPlay() {
if (!flag) {
flag = true;
utterance = new SpeechSynthesisUtterance(document.querySelector('#readFrom').innerHTML);
utterance.lang = 'nl-NL';
utterance.rate = 0.7;
utterance.onend = function () {
flag = false;
playEle.className = pauseEle.className = '';
stopEle.className = 'stopped';
};
playEle.className = 'played';
stopEle.className = '';
speak(utterance);
}
if (paused) {
playEle.className = 'played';
pauseEle.className = '';
resume();
}
}
function onClickPause() {
if (speaking && !paused) {
pauseEle.className = 'paused';
playEle.className = '';
pause();
}
}
function onClickStop() {
if (speaking) {
stopEle.className = 'stopped';
playEle.className = pauseEle.className = '';
flag = false;
cancel();
}
}
}
else { /* speech synthesis not supported */
msg = document.createElement('h5');
msg.textContent = "Detected no support for Speech Synthesis";
msg.style.textAlign = 'center';
msg.style.backgroundColor = 'red';
msg.style.color = 'white';
msg.style.marginTop = msg.style.marginBottom = 0;
document.body.insertBefore(msg, document.querySelector('div'));
}
}
</script>
</body>
It should be very simple. I see on your line that you are querying all the body text Content but that should not be it. Go on your JS Console and query: document.querySelector('body').textContent
You should see exactly what you are passing as arguments to:
utterance = new SpeechSynthesisUtterance(document.querySelector('body').textContent);
So now it's up to you, you would have to filter what you want to be read by putting it in a specific DIV or stripping HTML from the page according to a complex logic keeping just what you want to read.

How can I change style of element with jQuery function and media query when resize event working

I'm making a responsive web site, and I have some problems at resize.
I using media query at ww<1280, ww<1024, ww<640, then controll elements with Jquery Functions.
when document loaded, media query and functions are worked well.
but, when I try some jquery functions then resize window, there are so many problems.
one of function I wrote is,
var menuOpen = function() {
var ctryBtn = $(".countryMenu input[type=button]");
var ctryMenu = $(".countryMenu");
var subGnb = $("#subGnb");
var gnbBtn = $("#header button.mobileGnbBtn");
var myGnb = $("#gnb");
var schBtn = $(".mobileFindBtn");
var schMenu = $(".utilMenu");
var gnbDown = function () {
$("#gnb ul").append("<li class='mobileSiteMap'><a href='siteMap.html'>Site Map</a></li>");
myGnb.slideDown(500,function () {
$(".mobileGnbBtn").css({
"width":"37px",
"height":"37px",
"background-image":"url(image/common/btn-close-mobile.png)",
"background-size":"cover"
});
});
};
var gnbUp = function () {
if ($(window).width() <= 623) {
myGnb.slideUp(500, function () {
$(".mobileSiteMap").remove();
$(".mobileGnbBtn").css({
"width":"43px",
"height":"37px",
"background-image":"url(image/common/btn-menu-mobile.png)"
});
});
} else {
$(".mobileSiteMap").remove();
return false;
}
};
ctryBtn.on("click", function () {
if(isSubGNB === false){
subGnb.slideDown(500);
isSubGNB = true;
} else {
subGnb.slideUp(500);
isSubGNB = false;
}
});
gnbBtn.on("click", function () {
if(isGNB === false){
if(isSubGNB === true || isSearch === true){
subGnb.slideUp(500);
isSubGNB = false;
schMenu.slideUp(500);
isSearch = false;
ctryMenu.fadeIn(300);
}
gnbDown();
isGNB = true;
} else {
gnbUp();
isGNB = false;
}
});
schBtn.on("click", function () {
if (isSearch === false) {
if (isGNB === true || isSubGNB === true ) {
gnbUp();
isGNB = false;
subGnb.slideUp(500);
isSubGNB = false;
}
ctryMenu.fadeOut(100);
schMenu.slideDown(300);
isSearch = true;
} else {
schMenu.slideUp(100);
isSearch = false;
ctryMenu.fadeIn(300);
}
});
};
#gnb is absolute positioned at ww<640, invisible(display:none), and different children elements setting with another ww sizes.
#gnb is relative positioned at upper 640px ww.
Then I wrote resize event like:
$(window).on("resize", function () {
var gnbPC = function () {
$("#gnb").css({
"width":"410px",
"height":"76px",
"letter-spacing":"-0.04em",
"margin-left":"26.866%"
});
};
var toggleMobile = function () {
if ($(window).width() <= 623 ) {
$("#subGnb").css({"display":"none"});
} else {
gnbPC();
$("#subGnb").css({"display":"none"});
}
};
clearTimeout(timer);
timer = setTimeout(toggleMobile, delta);
});
I set var delta = null; var timer = null;
Under 640px ww, when I click button, #gnb slideDown, and slideUp well.
when #gnb slideUp, then I try resize to upper 640px,
there is no #gnb because it had invisibled when slideUp() finished.
So I try to give it CSS set(default value of CSS ww>640),
but it is written inline, then mediaQuery didn't work.
I want some solution, when I trying resize window,
function work then reload for default setting for ww size.
Or, solve this resizing problems.
I want reset when resize,
if #gnb opened, then I try resize, I want it closed then change to default setting for ww size.

Discover and fix the memory leak

I'm trying to find the memory leak in the example here:
document.addEventListener('DOMContentLoaded', bindTabs);
function bindTabs(){
var lastTab,
tabs = document.querySelectorAll(".tabs li"),
i;
function selectTab(){
activateTab(this);
loadContent(this.attributes["data-load"].value);
}
function activateTab(tab){
if (lastTab) {
lastTab.classList.remove("active");
}
(lastTab = tab).classList.add("active");
}
[].forEach.call(tabs, function(el){
el.addEventListener('click', selectTab, false);
});
}
function loadContent(url){
getContent(url).then(function(data){
prepareContent(data);
prepareGallery();
})
}
var lastDiv;
function prepareContent(data){
var content = document.getElementById("content"),
div = document.createElement("div");
div.innerHTML = data;
if (lastDiv) {
content.removeChild(lastDiv);
}
content.appendChild(div);
lastDiv = div;
}
function prepareGallery(){
var width = 426,
forward = false,
position = 0,
elements = document.querySelectorAll(".gallery li"),
number = elements.length;
function checkDirection() {
if (position === 0) {
forward = true;
} else if (position === (number - 1)) {
forward = false;
}
}
function changeLeftProperty() {
var value = (-1 * width * position) + "px";
[].forEach.call(elements, function(el) {
el.style.left = value;
});
}
function advance(){
position = position + (forward ? 1 : -1);
}
function move(){
checkDirection();
advance();
changeLeftProperty();
}
setInterval(move, 2000);
}
function getContent(url){
var callbacks = [],
xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function(e){
if (xhr.status == 200) {
callbacks.forEach(function(cb){
cb(xhr.response);
})
}
}
xhr.send()
return {
then: function(fn){
callbacks.push(fn)
}
}
}
I profiled the page by taking heap snapshots and running the timeline but unfortunately I wasn't able to find anything.
Can you suggest me where could be the problem and what is the exact memory leak (if any)?
There is setInterval(move, 2000); in prepareGallery that will be called every click, and there is no clearInterval.

Splitting HTML page into different sections using sliding panel dividers? How is it done?

I'm wanting to divide a web page up into different sections as shown here. I'm trying to figure it out what this technique is called and an efficient way to implement it?
The page is divided up into different sections giving the user the flexiblity to expand and contract the different sections using panel handles.
I'm assuming these aren't regular frames (which I'd like to avoid using anyways).
Does anybody know of a tutorial or good example out there besides the one on jsfiddle?
the idea is quite simple.
you break up the screen with some elements, it does not really matter which (say divs) with a given height.
then attach a onclick event to the handle that starts the drag. what the onclick does is attach a mousemove event to the body which will resize the elements.
here is something i wrote a while back (before my jquery days), i'm sure it could be written much better, and you might find a plugin for this, i don't know of one:
function WidenHandle(widenedELement, handleElement, ondblClick, startWidth, withCoverDiv, onDrop)
{
this.Handle = handleElement;
this.IsClosed = false;
this.Element = widenedELement;
this.LastX = 0;
this.LastY = 0;
this.AttachedDragFunction = null;
this.AttachedDropFunction = null;
this.StartWidth = startWidth ? startWidth : 300;
this.CoverDiv;
this.OnDrop = onDrop;
this.IsDragging = false;
if (withCoverDiv)
{
var coverDiv = document.createElement("div");
coverDiv.style.width = "2000px";
coverDiv.style.height = "2000px";
coverDiv.style.display = "none";
coverDiv.style.position = "fixed";
coverDiv.style.zIndex = "1000";
// coverDiv.style.backgroundColor = "red";
// coverDiv.style.opacity = "0.3";
coverDiv.style.top = '0px';
this.CoverDiv = coverDiv;
document.body.appendChild(coverDiv);
}
if (this.Handle.addEventListener)
{
this.Handle.addEventListener("mousedown", function(element)
{
return function(event)
{
element.StartDragging(event);
if (element.CoverDiv)
element.CoverDiv.style.display = "";
if (event.preventDefault)
event.preventDefault();
}
} (this), true);
this.Handle.addEventListener("dblclick", function(element)
{
return function(event)
{
element.Close(event);
if (element.CoverDiv)
element.CoverDiv.style.display = "none";
ondblClick(element);
}
} (this), true);
}
else
{
this.Handle.attachEvent("onmousedown", function(element)
{
return function(event)
{
element.StartDragging(event);
if (element.CoverDiv)
element.CoverDiv.style.display = "";
if (event.preventDefault)
event.preventDefault();
}
} (this));
this.Handle.attachEvent("ondblclick", function(element)
{
return function(event)
{
element.Close(event);
if (element.CoverDiv)
element.CoverDiv.style.display = "none";
ondblClick(element);
}
} (this), true);
}
}
WidenHandle.prototype.StartDragging = function(event)
{
this.IsDragging = true;
if (this.CoverDiv)
this.CoverDiv.style.display = "none";
this.ClearAttachedEvents();
this.LastX = this.GetX(event);
// ** attach mouse move and mouse up events to document ** //
this.AttachedDragFunction = function(element)
{
return function(event)
{
element.OnDragging(event);
}
} (this);
this.AttachedDropFunction = function(element)
{
return function(event)
{
element.OnDropping(event);
}
} (this);
if (window.attachEvent) // ie
{
document.attachEvent('onmousemove', this.AttachedDragFunction);
document.attachEvent('onmouseup', this.AttachedDropFunction);
}
else // ff
{
document.onmousemove = this.AttachedDragFunction;
document.onmouseup = this.AttachedDropFunction;
}
}
// ** for repositioning popup while dragging ** //
WidenHandle.prototype.OnDragging = function(event)
{
clearHtmlSelection();
this.WidenCell(event);
}
// ** for release popup movement when dropping ** //
WidenHandle.prototype.OnDropping = function(event)
{
this.IsDragging = false;
if (this.CoverDiv)
this.CoverDiv.style.display = "none";
this.ClearAttachedEvents();
if (this.OnDrop)
this.OnDrop();
}
WidenHandle.prototype.ClearAttachedEvents = function()
{
// ** detach events from document ** //
if (window.attachEvent) // ie
{
document.detachEvent('onmousemove', this.AttachedDragFunction);
document.detachEvent('onmouseup', this.AttachedDropFunction);
}
else // ff
{
document.onmousemove = null;
document.onmouseup = null;
}
}
WidenHandle.prototype.GetX = function(event)
{
// ** return x position of mouse ** //
var posx = 0;
if (!event) event = window.event;
if (event.pageX)
{
posx = event.pageX;
}
else if (event.clientX)
{
posx = event.clientX;
}
return posx;
}
WidenHandle.prototype.WidenCell = function(event)
{
if (!this.Element.style.width)
this.Element.style.width = this.Element.offsetWidth - 9 + "px";
var width = parseInt(this.Element.style.width) + (this.GetX(event) - this.LastX);
if (width > 13)
this.Element.style.width = width + "px";
// ** remember last mouse position ** //
this.LastX = this.GetX(event);
}
WidenHandle.prototype.Close = function(event)
{
var width = parseInt(this.Element.style.width);
if (width < 30)
{
this.IsClosed = false;
this.Element.style.width = "";
return;
// width = this.StartWidth;
}
else
{
width = 14;
this.IsClosed = true;
}
this.Element.style.width = width + "px";
}
function clearHtmlSelection()
{
var sel;
if (document.selection && document.selection.empty)
{
document.selection.empty();
}
else if (window.getSelection)
{
sel = window.getSelection();
if (sel && sel.removeAllRanges) sel.removeAllRanges();
}
}

Categories

Resources