gpt4 book ai didi

javascript - 仅通过单击特定元素的按钮更改样式表

转载 作者:行者123 更新时间:2023-12-03 16:33:10 25 4
gpt4 key购买 nike

所以,这个问题是基于我目前正在做的一份作业。我获得了一个 HTML 文档和两个样式表。 HTML 文档非常简单:

<html>
<head>
<title>DOM-scripting: change style</title>
<link rel="stylesheet" href="style/style1.css" id="stylesheet"/>
</head>
<body>
<nav class="chooseStyle">
<input type="button" id="style1Button" value="Style 1"/>
<input type="button" id="style2Button" value="Style 2"/>
</nav>
<article>
<h1>Style change using DOM-scripting</h1>
<p> sample text </p>
<p> sample text </p>
<p> sample text </p>
</article>
<nav class="links">
<ul>
<li><a href="link">school name</a></li>
<li><a href="link">school name</a></li>
</nav>

<script src="scriptToUse.js"></script>
</body>
</html>

style1.css 包含以下内容:

body {
background-color: #676632;
}

input[type="button"] {
color: #F5F265;
background-color: #9B9302;
}

article {
margin-left: 150px;
margin-right: 150px;
text-indent: 20px;
color: #C9C892;
}

h1 {
color: #EEF1BA;
text-align: center;
}

a {
color: #A1FA56;
text-decoration: none;
font-weight: bold;
}

ul {
padding: 0;
}

li {
list-style-type: none;
}

Style2.css 包含以下内容:

body {
color: #EEEEAA;
}

input[type="button"] {
color: #9B9302;
background-color: #F5F265;
}

article {
margin-left: auto;
margin-right: auto;
text-align: justify;

color: #A3A163;
}

h1 {
color: #AAAA66;
text-align: left;
}

a {
color: #CDCF9B;
}

ul {
padding: 0;
}

li {
list-style-type: none;
}

练习的第一部分指出我需要创建一个 JavaScript 文件,该文件允许网页的样式表根据单击的按钮进行更改。第一个按钮引用第一个样式表,第二个按钮引用第二个样式表。我发现这相当简单,一切正常。

但是,练习的第二部分说明如下:“现在编辑 javascript 文件,以便单击按钮时仅更改文章的样式。不要编辑 CSS 文件。”这意味着样式表的 href 仍然应该更改,就像第一部分一样,但现在它可能只影响文章元素的样式,而不是整个页面的样式。

在过去的一个小时里我一直在寻找相关问题,但似乎没有什么真正能提供解决方案。我读过一些问题,指出不可能将样式表仅应用于特定元素而不更改样式表本身的任何内容。请记住,我才大学一年级,才刚刚开始学习 javascript,这意味着解决方案应该不难找到。我猜?

我到目前为止编写的Javascript代码:

'use strict';

const handleLoad = () => {
let style1 = document.getElementById('style1Button');
let style2 = document.getElementById('style2Button');
style1.addEventListener('click', handleClick);
style2.addEventListener('click', handleClick);
};

const handleClick = (event) => {
if(event.target.value === "Style 1") {
document.getElementById("stylesheet").href = "style/style1.css";
// should only change article style
// currently still referring to the whole document
} else {
document.getElementById("stylesheet").href = "style/style2.css";
// should also only change article style
// also still referring to the whole document
}
};

window.addEventListener('load', handleLoad);

有什么办法可以阻止除article元素之外的所有元素的CSS规则吗?或者也许更改不应该受到影响的元素的类或 ID?

提前非常感谢:)


终于解决了这个问题。 (代码可能不是那么紧凑和正确,但它可以工作,所以我非常高兴:D):

'use strict';

const handleLoad = () => {
let style1 = document.getElementById('style1Button');
let style2 = document.getElementById('style2Button');
style1.addEventListener('click', handleClick);
style2.addEventListener('click', handleClick);
makeShadow();
};

const handleClick = (event) => {
let article = document.querySelector('article');
let shadow = article.shadowRoot;

let style = event.target.value === "Style 1" ? "style/style2.css" : "style/style1.css";

for(let node of shadow.childNodes) {
if(node.hasAttribute('href')){
node.href = style;
}
}
};

const makeShadow = () => {
let article = document.querySelector('article');
let articleClone = makeClone(article);

let shadow = article.attachShadow({mode:'open'});

let link = document.createElement('link');
link.rel = "stylesheet";
link.href = 'style/style1.css';

shadow.appendChild(articleClone);
shadow.prepend(link);
};

const makeClone = (article) => {
let clone = article.cloneNode();
clone.innerHTML = article.innerHTML;
return clone;
};

window.addEventListener('load', handleLoad);

最佳答案

在这种情况下,我们可以利用shadowRoot作为样式的封装。

这个想法就像在一个只有 article 元素的页面中添加一个包含大量样式的 css 文件,显然其他样式不会有任何效果。

我们可以使用 shadowRoot 进行同样的操作,将文章放入它自己的小世界中,并添加一个包含更多样式的文件。

该代码有大量注释。如果您有任何问题请发表评论:)

首先加载时我们准备阴影元素:

const handleLoad = () => {

// Old Code for button handlers still needed
let style1 = document.getElementById('style1Button');
let style2 = document.getElementById('style2Button');
style1.addEventListener('click', handleClick);
style2.addEventListener('click', handleClick);


// New Code Below

// Select the article from the page
const article = document.querySelector('article');
// Create an empty div Element to work as a bucket
const placeholderElement = document.createElement('div');
// set it's id attribute to select it later
placeholderElement.setAttribute('id', 'placeholderElementShadowRot')
// replace the article with our div in the document
// the article element is not completly lose at this point
// we still have in the variable article
article.replaceWith(placeholderElement);
// attache a shadow to the div element
const shadow = placeholderElement.attachShadow({ mode: 'open' });
// sets the shadow's innerHTML equal to article outerHTML
shadow.innerHTML = article.outerHTML;


// create a link
const link = document.createElement('link');
// set it's href attribute to the first style file
link.setAttribute("href", 'style1.css');
// set the rel attribute
link.setAttribute("rel", "stylesheet");
// add the link to the shadow
shadow.appendChild(link)
};

点击按钮

const handleClick = (event) => {
// Select our div we created before using the id
const placeholderElement = document.querySelector('#placeholderElementShadowRot');
// since we already attached a shadow
// we can use it through the property .shadowRoot
const shadow = placeholderElement.shadowRoot;

// based on which button we add the relevant style file
if (event.target.value === "Style 1") {
shadow.querySelector('link').setAttribute("href", "style1.css")
} else {
shadow.querySelector('link').setAttribute("href", "style2.css")
}
};

注意:你的 JS 中有一个拼写错误,处理程序称为 handleclick 小写 click 但你添加了一个大写 Click handleClickaddEventListener

关于javascript - 仅通过单击特定元素的按钮更改样式表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62132821/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com